fgets() 工作很笨拙
fgets() is working awkwardly
所以很长一段时间以来我一直使用 scanf(),但是当输入比字符串长时它总是困扰我,所以它弄乱了代码(更改其他整数等)。
所以我被告知我应该改用 fgets(),因为它可以限制它读取的字母和符号的数量。
但是 fgets() 总是也包括换行符 (\n),所以我被建议使用命令 input[strcspn(input, "\r\n")] = '[=11=]';
,它应该从字符串中删除 \n。
当然还有一个问题。当输入比字符串长时,会发生以下两种情况之一:
1.它把输入留在屏幕上,只将我的光标向下移动一行,这有效地软锁定了我的程序。(不正确,通过使程序正确循环来修复它)
- 它会跳过下一个 fgets()(一个或多个)。
我在某处读到这可能是因为 fgets() 在下次调用时读取输入的其余部分,但我每次都尝试清空字符串,然后再次写入它,但它没有一点帮助位.
有人知道如何解决这个问题吗?这已经困扰我一段时间了,因为我从来没有实现过对字符串程序的完美输入(当人们犯错误时使用故障保险)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char input[3];
int main(){
begin:
fgets(input, 3, stdin);
input[strcspn(input, "\r\n")] = '[=10=]';
if(strcmp(input, "1")==0){
printf("input = 1\n");
}
else if(strcmp(input, "2")==0){
printf("input = 2\n");
}
goto begin;
}
很遗憾,我无法重现第一个问题,但第二个问题可以通过键入 xx1 或 xx2 解决。
提前致谢!
您应该通过测试最后一个字符是否为换行符来检查 fgets()
是否读取了整行。如果是,用空字节替换换行符;如果没有,请继续阅读字符,直到换行为止。
char *c = fgets(input, 3, stdin);
if (c == NULL) { // EOF reached
break;
}
if (input[strlen(input)-1] == '\n') {
input[strlen(input)-1] = '[=10=]';
} else {
int c;
while ((c = getchar()) != '\n' && c != EOF) {
}
}
以下建议代码::
- 消除了
goto
- 利用
fgets()
的返回值
- 不包含头文件那些内容没有用到
- 允许“\n”处理任何其他 'end of line' 序列。
- 消除了 'magic' 个数字
现在建议的代码:
#include <stdio.h>
#include <string.h>
#define BUF_LEN 3
char input[ BUF_LEN ];
int main( void )
{
while( fgets(input, sizeof input, stdin) )
{
input[strcspn(input, "\n")] = '[=10=]';
if(strcmp(input, "1")==0){
printf("input = 1\n");
}
else if(strcmp(input, "2")==0){
printf("input = 2\n");
}
}
}
这是典型的 运行 代码(请记住,即使没有打印任何内容,循环仍在继续:
1
input = 1
2
input = 2
3
4
5
6
1
input = 1
kj;lkj;lkj
1jklkl;j
1
input = 1
x1
xx1
input = 1
所以很长一段时间以来我一直使用 scanf(),但是当输入比字符串长时它总是困扰我,所以它弄乱了代码(更改其他整数等)。
所以我被告知我应该改用 fgets(),因为它可以限制它读取的字母和符号的数量。
但是 fgets() 总是也包括换行符 (\n),所以我被建议使用命令 input[strcspn(input, "\r\n")] = '[=11=]';
,它应该从字符串中删除 \n。
当然还有一个问题。当输入比字符串长时,会发生以下两种情况之一:
1.它把输入留在屏幕上,只将我的光标向下移动一行,这有效地软锁定了我的程序。(不正确,通过使程序正确循环来修复它)
- 它会跳过下一个 fgets()(一个或多个)。
我在某处读到这可能是因为 fgets() 在下次调用时读取输入的其余部分,但我每次都尝试清空字符串,然后再次写入它,但它没有一点帮助位.
有人知道如何解决这个问题吗?这已经困扰我一段时间了,因为我从来没有实现过对字符串程序的完美输入(当人们犯错误时使用故障保险)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char input[3];
int main(){
begin:
fgets(input, 3, stdin);
input[strcspn(input, "\r\n")] = '[=10=]';
if(strcmp(input, "1")==0){
printf("input = 1\n");
}
else if(strcmp(input, "2")==0){
printf("input = 2\n");
}
goto begin;
}
很遗憾,我无法重现第一个问题,但第二个问题可以通过键入 xx1 或 xx2 解决。
提前致谢!
您应该通过测试最后一个字符是否为换行符来检查 fgets()
是否读取了整行。如果是,用空字节替换换行符;如果没有,请继续阅读字符,直到换行为止。
char *c = fgets(input, 3, stdin);
if (c == NULL) { // EOF reached
break;
}
if (input[strlen(input)-1] == '\n') {
input[strlen(input)-1] = '[=10=]';
} else {
int c;
while ((c = getchar()) != '\n' && c != EOF) {
}
}
以下建议代码::
- 消除了
goto
- 利用
fgets()
的返回值
- 不包含头文件那些内容没有用到
- 允许“\n”处理任何其他 'end of line' 序列。
- 消除了 'magic' 个数字
现在建议的代码:
#include <stdio.h>
#include <string.h>
#define BUF_LEN 3
char input[ BUF_LEN ];
int main( void )
{
while( fgets(input, sizeof input, stdin) )
{
input[strcspn(input, "\n")] = '[=10=]';
if(strcmp(input, "1")==0){
printf("input = 1\n");
}
else if(strcmp(input, "2")==0){
printf("input = 2\n");
}
}
}
这是典型的 运行 代码(请记住,即使没有打印任何内容,循环仍在继续:
1
input = 1
2
input = 2
3
4
5
6
1
input = 1
kj;lkj;lkj
1jklkl;j
1
input = 1
x1
xx1
input = 1