很多情况下,我们需要知道用户输入的字符串的长度,以便进行下一步工作。
很多读者立即想起了strlen()函数,其实是有问题的,请看下面的代码:
#include <stdio.h>
#include <string.h>
int main(){
char str[21];
int strLen;
printf("Input your string: ");
scanf("%s", str);
strLen = strlen(str);
printf("string = %s\nlength = %d\n", str, strLen);
return 0;
}
运行结果:
直接通过scanf()读取的字符串,如果超过缓冲区的长度,会提示程序停止运行,而且缓冲区最后一个字节不是NUL,strlen()统计字符串长度可能会出错。
另外,输入的字符串中不能包含空格,因为scanf()读取数据是以空格为分隔的,空格后边的字符串将会赋值给另一个变量。
所以,直接通过scanf()读取字符串并,然后用strlen()统计长度是不行的。
下面的代码,通过getchar()一个一个读取输入的字符来计算长度。
#include <stdio.h>
#define MAXLEN 10 // 能够统计的字符串的最大长度
int getStr(char line[], int nmax);
int main(void){
int strLen;
char buffer[MAXLEN+1];
while(1){
printf("Input your string: ");
strLen = getStr(buffer, MAXLEN);
if (strLen==0) // 输入空行,结束程序
break;
printf("string = %s\nlength = %d\n\n", buffer, strLen);
};
}
int getStr(char *buffer, int maxLen){
char c; // 读取到的一个字符
int len = 0; // 当前输入的字符串的长度
// 一次读取一个字符,保存到buffer
// 直到遇到换行符(\n),或者长度超过maxLen时,停止读取
while( (c=getchar()) != '\n' ){
buffer[len++]=c; // 将读取到的字符保存到buffer
if(len>=maxLen){
break;
}
}
buffer[len]='\0'; // 读取结束,在末尾手动添加字符串结束标志
fflush(stdin); // 刷新输入缓冲区
return len;
}
运行结果:
Input your string: 123456
string = 123456
length = 6
Input your string: 1234567890
string = 1234567890
length = 10
Input your string: 123456789012345
string = 1234567890
length = 10
Input your string: www.coderbbs.com
string = www.coderb
length = 10
Input your string:
上面的代码,最多读取 MAXLEN 长度的字符串,并且允许中间出现空格。
长度超过MAXLEN时,截取前MAXLEN个字符,丢掉后边的,不会造成程序错误。
注意:因为字符串最后要多出一个终止符NUL(/0),缓冲区的长度至少要比字符串最大长度大1,这就是buffer的长度为 MAXLEN+1 的原因。
这里重点说明的是getchar()函数。getchar()是有缓冲区的,程序运行到getchar()会暂停,等待用户输入,并将输入的内容保存在输入缓冲区,直到缓冲区满或者按下回车键,才开始读取缓冲区中的内容。读完缓冲区,或者读到第MAXLEN个字符,getStr()函数执行结束,返回读取的长度。
但是,getchar()函数还有一个特性:如果输入缓冲区中有数据,会直接读取,不等待用户输入,只有在没有数据的情况下才等待用户输入。如果用户输入的字符串长度大于MAXLEN,那么getStr()函数第一次执行结束后,不会等待用户输入,会继续读取缓冲区中剩下的内容。所以,每次执行完getStr(),要清空缓冲区的数据,这就是 fflush(stdin) 语句(程序第32行)的作用。
更多关于缓冲区和getchar()的内容请查看:对C语言输入输出流和缓冲区的深入理解
fflush()函数用来刷新缓冲区,其原型为:
int fflush(FILE* stream);
stream为要刷新的缓冲区,stdin表示标准输入缓冲区。
如果没有 fflush(stdin) 语句,输入的字符串过长时,会有下面的现象:
Input your string: 123456
string = 123456
length = 6
Input your string: 12345678901234
string = 1234567890
length = 10
Input your string: string = 1234
length = 4
Input your string: http://www.coderbbs.com
string = http://www
length = 10
Input your string: string = .coderbbs.
length = 10
Input your string: string = com
length = 3
Input your string:
程序会将缓冲区的剩余内容也读取出来,不会丢掉过长的内容。