字符串的神奇应用–02、字符串的输入
C语言常用的输入方式为scanf()函数,借助%s可以通过屏幕录入字符串;此外字符串独有的输入函数还有gets() 、fgets() 、gets_s() 、sgets() 函数等,除了函数的差别,还有遇到需要输入多组字符串的情况的典型案例。
字符串输入函数
char str[1001];
scanf("%s“,&str));
scanf("%s“,str)); //数组中str 和 &str 都表示指向数组首位置的指针
gets(str);
fgets(str,1001,stdin);
gets_s(str,1001);
scanf()只能读取一个单词,需要读取整行输入时,用到gets()函数。gets()函数的缺点:只有一个参数(数组的首地址)不知道数组是否能够接收完整行的单词,存在数组溢出风险,get()因其不安全性已经在被移除出C11标准,***转而使用更安全的fgets()函数,增加第二个int类型限制输入的字符,fgets()函数只会读取屏幕中n-1个字符写入数组str中,最后一个位置补上一个’\0’。但fgets()函数中输入字符数小于第二个int参数时,字符串会将换行符一起写入字符中,字符串结尾变成----\n\0。
给出一种处理换行符的方法:
while(str[i] != '\n')
{
i++;
}
str[i] = '\0' ;
gets_s()函数只从标准输入中读取数据,故不需要第三个参数,与fgets()不同的是,gets_s()碰到换行符时会丢弃换行符,而不是存储,第二个不同点是,当输入的字符总数超过参数限制时,gets_s会将数组首地址的字符替换为空字符,返回NULL指针,然后调用特殊的“处理函数”,程序终止。
综上,fgets()是最安全的字符串输入函数。
自制函数s_gets()
char * s_gets(char * st, int n)
{
char * ret_val;
int i = 0;
ret_val = fgets(st, n, stdin);
if(ret_val) //ret_val != NULL
{
while(st[i] != '\n' && st[i] != NULL )
{ i++; }
if(st[i] == '\n' )
{ st[i] = '\0'; }
else
{
while(getchar() != '\n' )
{ continue; }
}
}
return ret_val;
}
以上自制的s_gets()函数可以规避掉fgets()末尾换行符的问题。
字符串输入举例
已知字符串数量,未知字符串长度
题目1:
对于每组测试数据:
第一行:n — 砝码的种数(范围[1,10])
第二行:m1 m2 m3 … mn — 每种砝码的重量(范围[1,2000])
第三行:x1 x2 x3 … xn — 每种砝码对应的数量(范围[1,10])
int cnt;
int *weight;
int *num;
int i, j, k;
int total;
char *map;
while(scanf("%d", &cnt) != EOF)
{
total = 1;
weight = (int* )calloc(cnt, sizeof(int)); //可变数组
num = (int *)calloc(cnt, sizeof(int)); //可变数组
for(i=0; i<cnt; i++)
{
scanf("%d", weight+i); //每钟重量
}
for(i=0; i<cnt; i++)
{
scanf("%d", num+i); //输入每种数量
}
}
以上是一种,已知两个数组,未知数组长度的输入方法。
未知字符串数量,已知字符串最大长度
题目2:
输入:
第一行一个整数N,接下来N行每行一个字符串
char n[100][10001];
int N = 0;
scanf("%d",&N);
for (int i = 0; i<N; i++)
{
scanf("%s",n[i]);
}
以上,最简单的方法,不检查各种不规范的输入,用于刷算法题刚好够用。
未知字符串数量,未知字符串长度
题目3:
输入:
abcd12345ed125ss123058789
a8a72a6a5yy98y65ee1r2
while(scanf("%s",str)!=EOF)
{ //已经算完成一个字符串str的输入,可以对字符串进行处理
/* 输入一个换行符处理一次,直到用<Ctrl + z>组合键
*然后按 Enter 键结束。
*/
}
以上,是字符串常见的输入函数和常见的集中输入条件的解决方案。