C语言输入输出汇总
刷题时经常遇到C语言的输入问题,包括一行读入数字、字符串、十六进制数等等,本文将对此进行一一分类编写.
#include <ctype.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int get_data(int *nums);
long StrToHex(char *data);
int judgeHexStr(char *data);
unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base);
int main() {
/*
1 . 常规输入整行,$ My name is shenjianliang
My name is shenjianliang
*/
#if 0
char strline[100] = {'\0'};
gets(strline);
printf("input : %s\n", strline);
return 0;
#endif
/*
2 . 按空格隔开输入,使用scanf和二维数组,假设单词长度不超过20,总数不超过100
My name is shenjianliang
*/
#if 0
//按 Enter 后程序输出并退出
char input[100][20];
int i = 0;
int count = 0;
while (scanf("%s", &input[count++]) > 0) {
if (getchar() == '\n') //判断是否检测到 Enter
break;
}
for (i = 0; i < count; i++) {
printf("input[%d] = \t %s\n", i, input[i]);
}
return 0;
#endif
/*
3 . 按行输入,使用双指针,假设单词长度不超过20,总数不超过100
My
name
is
shenjianliang
*/
#if 0
//按 Enter
//退出循环无法实现,此类题目一般靠有多少个输入或者最后一行等于end判断结束
char strline[100][20];
int i = 0;
// int N;
// scanf ("%d\n",&N);
// for (i = 0;i< N;i++){
// gets(strline[i]);
// printf ("strline[%d] = \t%s\n",i,strline[i]);
// }
int count = 0;
while (gets(strline[count++]) != NULL) {
if (!strcmp(strline[count - 1], "end")) {
break;
}
}
for (i = 0; i < count; i++) {
printf("strline[%d] = \t %s\n", i, strline[i]);
}
return 0;
#endif
/*
4 . 按逗号隔开输入(最难),使用双指针,条件同上
etgerwty,,,rtyer,,,rteyerty,
count = 3
input[0] = etgerwty
input[1] = rtyer
input[2] = rteyerty
*/
#if 0
char input[20][100]; //使用二维数组
char str[1000];
char *ptr;
int count = 0;
gets(str);
int i = 0;
ptr = strtok(str, ",");
while (ptr != NULL) {
// count ++;
strcpy(input[count++], ptr);
ptr = strtok(NULL, ",");
}
printf("count = %d\n", count);
for (i = 0; i < count; i++) {
printf("input[%d] = \t %s\n", i, input[i]);
}
return 0;
#endif
#if 0
char **input, **temp; //使用双指针 ,效果不好,不便于输出
input = (char **)malloc(sizeof(char **) * 100); //声明100个字符串组成的数组
temp = input; //存放开始的地址
char str[1000];
gets(str);
//*input = (char *) malloc (sizeof(char *)*20 );//第一个字符串数组分配空间
//不分配也可以
*input = strtok(str, ",");
int count = 0;
while (*input != NULL) {
count++;
*input++;
//*input = (char *) malloc (sizeof(char *)*20 ); // 不分配也可以
*input = strtok(NULL, ",");
}
input = temp; //恢复指针初始位置
for (int i = 0; i < count; i++) {
printf("input[%d] = \t %s\n", i, input[i]); //以二维数组的形式打印输出
}
return 0;
#endif
/*
5 . 数字输入,空格隔开
12 23 445 345 12342435
*/
#if 0
//按 Enter 后程序输出并退出
int input[100];
int count = 0;
while (scanf("%d", &input[count++]) != EOF) {
if (getchar() == '\n') //判断是否检测到 Enter
break;
}
printf("count = %d \n", count);
for (int i = 0; i < count; i++) {
printf("input[%d] = \t %d\n", i, input[i]);
}
return 0;
#endif
/*
6 . 数字输入,逗号隔开
Example 1:
452345, 645 6345,63776 ,37657, 214545 ,526
count = 6
input[0] = 452345
input[1] = 645
input[2] = 63776
input[3] = 37657
input[4] = 214545
input[5] = 526
Example 2:
2344, , ,3545,,365
count = 5
input[0] = 2344
input[1] = 0
input[2] = 0
input[3] = 3545
input[4] = 365
*/
#if 0
int num_input[20];
char str[1000];
char *ptr;
int count = 0;
gets(str);
ptr = strtok(str, ",");
while (ptr != NULL) {
num_input[count++] = atoi(ptr);
ptr = strtok(NULL, ",");
}
printf("count = %d\n", count);
for (int i = 0; i < count; i++) {
printf("input[%d] = \t %d\n", i, num_input[i]);
}
return 0;
#endif
/*
7 . 多组输入,数据总量不相同
N 组数据
1,2,3,4 //伤害值数组,不定长
20,30,15 //怪物生命值,不定长
5,6,7,8 //不同箭的数量,与伤害值种类对应
// 下面是第二组数据
4,2,3,4,7,8,9 //伤害值数组,不定长
50,30,15,234,44 //怪物生命值,不定长
5,6,7,8,66,77,88 //不同箭的数量,与伤害值种类对应
// 下面是第三组数据
1,2,3,4,45 //伤害值数组,不定长
20,60,11 //怪物生命值,不定长
5,6,7,8,34 //不同箭的数量,与伤害值种类对应
*/
#if 0
int N = 0;
int *damage, *health, *arrow_count;
scanf("%d\n", &N);
int damage_length = 0, health_length = 0, arrow_count_length = 0;
for (int i = 0; i < N; i++) {
damage = (int *)malloc(sizeof(int) * 20);
health = (int *)malloc(sizeof(int) * 20);
arrow_count = (int *)malloc(sizeof(int) * 20);
damage_length = get_data(damage);
health_length = get_data(health);
arrow_count_length = get_data(arrow_count);
printf("=============== start print =================\n");
for (int j = 0; j < damage_length; j++) {
printf("damage[%d] = %d\n", j, damage[j]);
}
for (int j = 0; j < health_length; j++) {
printf("health[%d] = %d\n", j, health[j]);
}
for (int j = 0; j < arrow_count_length; j++) {
printf("arrow_count[%d] = %d\n", j, arrow_count[j]);
}
printf("================ end print =================\n");
free(damage);
free(health);
free(arrow_count);
}
#endif
#if 1
int N = 0;
int damage[20], health[20], arrow_count[20];
scanf("%d\n", &N);
int damage_length = 0, health_length = 0, arrow_count_length = 0;
for (int i = 0; i < N; i++) {
damage_length = get_data(damage);
health_length = get_data(health);
arrow_count_length = get_data(arrow_count);
printf("=============== start print =================\n");
for (int j = 0; j < damage_length; j++) {
printf("damage[%d] = %d\n", j, damage[j]);
}
for (int j = 0; j < health_length; j++) {
printf("health[%d] = %d\n", j, health[j]);
}
for (int j = 0; j < arrow_count_length; j++) {
printf("arrow_count[%d] = %d\n", j, arrow_count[j]);
}
printf("================ end print =================\n");
}
#endif
/*
8 . 读入十六进制字符串,空格隔开
0x123 0xaaaa 100 0x01111 00x10 0x101 101 x xx 10ac x01
a[0] H: 0x123 O: 291
a[1] H: 0xaaaa O: 43690
a[2] H: 0x100 O: 256
a[3] H: 0x1111 O: 4369
a[4] H: 0x0 O: 0 //00x101为0 和 0x10 = 16
a[5] H: 0x10 O: 16
a[6] H: 0x101 O: 257
a[7] H: 0x101 O: 257 //x 和 xx不计入
a[8] H: 0x0 O: 0
//由于有x和xx,10ac和x01无法输入
*/
#if 0
long a[20];
int count = 0;
while (scanf("%lx", &a[count++])) {
if (getchar() == '\n') break;
}
for (int i = 0; i < count; i++) {
printf("a[%d]\t\tH: 0x%lx\t\tO: %ld\n", i, a[i], a[i]);
}
return 0;
#endif
/*
9 . 读入十六进制字符串,逗号隔开,判断后使用字符串格式输出
0xaabb,0x1234,0xffff,0x10000000
a[0] = 0xaabb
a[1] = 0x1234
a[2] = 0xffff
a[3] = 0x10000000
*/
#if 0
char a[20][100]; //使用二维数组
char str[1000];
char *ptr;
int count = 0;
gets(str);
int i = 0;
ptr = strtok(str, ",");
while (ptr != NULL) {
if (judgeHexStr(ptr) == 0) { //判断格式
strcpy(a[count++], ptr);
} else {
ptr = strtok(NULL, ",");
continue;
}
ptr = strtok(NULL, ",");
}
for (i = 0; i < count; i++) {
printf("a[%d] = \t %s\n", i, a[i]);
}
return 0;
#endif
/*
10 . 读入十六进制字符串,逗号隔开,使用十六进制和十进制格式输出
0x123,0xaaaa,100,0x01111,00x10,0x101,101,x,xx,10ac, ,x01
output[0] H: 0x123 O: 291
output[1] H: 0xaaaa O: 43690
output[2] H: 0x100 O: 256
output[3] H: 0x1111 O: 4369
output[4] H: 0x101 O: 257
output[5] H: 0x101 O: 257
output[6] H: 0x10ac O: 4268
*/
#if 0
char str[1000];
long output[20];
char *ptr;
int count = 0;
gets(str);
int i = 0;
ptr = strtok(str, ",");
while (ptr != NULL) {
output[count] = StrToHex(ptr);
ptr = strtok(NULL, ",");
if (output[count] == -1) {
continue; //不是标准十六进制字符串则舍弃
}
count++;
}
for (i = 0; i < count; i++) {
printf("output[%d]\t\tH: 0x%lx\t\tO: %ld\n", i, output[i], output[i]);
}
return 0;
#endif
/*
11 . 进制转换
0xaa 111 98 aa 64 0Xaa 100fg //非法字符自动截断
(16) a = 170 (10) a = 170 (8) a = 170
(16) a = 273 (10) a = 111 (8) a = 73
(16) a = 152 (10) a = 98 (8) a = 0
(16) a = 170 (10) a = 0 (8) a = 0
(16) a = 100 (10) a = 64 (8) a = 52
(16) a = 170 (10) a = 170 (8) a = 170
(16) a = 4111 (10) a = 100 (8) a = 64
*/
#if 0
// char *a;
// a = (char *)malloc (sizeof(char) * 20);
char a[20];
char **endp;
while (scanf("%s", a) != EOF) {
printf("(16)\t a = %ld\t", simple_strtoul(a, NULL, 16));
printf("(10)\t a = %ld\t", simple_strtoul(a, NULL, 10));
printf("(8)\t a = %ld\n", simple_strtoul(a, NULL, 8));
}
return 0;
#endif
}
int get_data(int *nums) {
int count = 0, data = 0;
char str[1000];
gets(str);
char *ptr;
ptr = strtok(str, ",");
while (ptr != NULL) {
nums[count++] = atoi(ptr);
ptr = strtok(NULL, ",");
}
return count;
}
//将十六进制字符串转换为整数(long)
long StrToHex(char *data) {
//使用自己写的函数00x不可以识别
if (judgeHexStr(data) != 0) {
return -1;
}
long ret = 0, s = 1;
int length = strlen(data);
for (int i = length - 1; i >= 0; i--) {
if (('0' <= data[i]) && (data[i] <= '9')) {
s = 1;
for (int j = 0; j < length - i - 1; j++) {
s = s * 16;
}
ret += ((int)(data[i] - '0')) * s;
} else if (('a' <= data[i]) && (data[i] <= 'f')) {
s = 1;
for (int j = 0; j < length - i - 1; j++) {
s = s * 16;
}
ret += ((int)(data[i] - 'a' + 10)) * s;
} else if (('A' <= data[i]) && (data[i] <= 'F')) {
s = 1;
for (int j = 0; j < length - i - 1; j++) {
s = s * 16;
}
ret += ((int)(data[i] - 'A' + 10)) * s;
} else {
continue;
}
}
return ret;
}
//判断是否为标准 0xaA12 或者 0XaA12 或者 aA12 格式
int judgeHexStr(char *data) {
if (data == NULL) {
return -1;
}
int length = strlen(data);
if (length == 0) {
return -1;
} else if (length >= 1) {
for (int i = 0; i < length; i++) {
if ((data[i] == 'x') || (data[i] == 'X')) {
// if (i == 0)
// {
// return -1;
// }
if (i != 1) //改为判断第二位是否为x
{
return -1;
}
for (int j = 0; j < i; j++) {
if (data[j] != '0') {
return -1;
}
}
} else {
// if ((('a' <= data[i]) && (data[i] <= 'f')) ||
// (('A' <= data[i]) && (data[i] <= 'F')) ||
// (('0' <= data[i]) && (data[i] <= '9'))) {
//等同于isxdigit(data[i]
if (isxdigit(data[i])) {
continue;
} else {
return -1;
}
}
}
}
return 0;
}
//进制转换
//如果输入为 0xff 或者 0Xff 格式,则默认转化为16进制
//如果输入有 8~9,则转化为十进制和十六进制
//如果输入为 a~f,则只能转为十六进制
//输入遇到非法字符则自动截断
unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) {
unsigned long result = 0;
unsigned long value;
if (*cp == '0') {
cp++;
if ((*cp == 'x' || *cp == 'X') &&
isxdigit(cp[1])) { //判断是否 0x 开头,0x 开头则为十六进制数
base = 16;
cp++;
}
if (!base) { //如果不是 0x 开头,base = 8
base = 8;
}
}
if (!base) {
base = 10;
}
while (isxdigit(*cp) && // cp在的值0~f范围内,否则跳出循环
(value = isdigit(*cp) ? *cp - '0' //如果cp的值在0~9
: (islower(*cp) ? toupper(*cp) : *cp) - 'A' +
10) < base) { //或者变为大写-'A'+10
result = result * base + value; //从左往右,数值 x base +最低位的值
cp++;
}
if (endp) {
*endp = (char *)cp; //捕获最低位地址
}
return result;
}