fgets() 未按预期运行
fgets() doesn't function as expected
这是我的代码
int main(){
int N,i,radius,diameter,count =0;
char str[20];
char color[N][20];
printf("Get the num : ");
scanf("%d",&N);
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
}
for(i=0;i<N;i++){
printf("%s",color[i]);
}
return 0;
}
给定的输入是:
N = 3
red 50,
50 green,
blue 50
这里的问题是如果 N
为 3,则 for 循环中的 fgets
只执行两次。如果我注释 scanf
语句,则不会出现此问题。谁能解释一下是什么导致了这个问题以及如何解决它?
经过几个小时的摸索,我意识到以下几点:
- 避免使用 scanf。管理缓冲区溢出并不容易。
- 始终尝试使用 fgets 获取用户输入。
在这里试试这个代码:
#include<stdio.h>
#include<stdlib.h>
int main(){
int N,i,radius,diameter,count =0;
char str[20];
printf("Get the num : ");
char buffer[64];
fgets(buffer, 64, stdin);
N = strtoul(buffer,NULL,10);
char color[N][20];
printf("%d\n",sizeof(color));
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
if(color[i][strlen(color[i])-1]=='\n'){
color[i][strlen(color[i])-1]='[=10=]';
}
else{
while((getchar())!='\n');//this is just to prevent an overflow for the size of char arrays
}
}
for(i=0;i<N;i++){
printf("%s\n",color[i]);
}
return 0;
}
请注意,我首先在一个字符数组中输入了一个数字。使用 strtoul(string to unsigned long) 将其转换为数字。现在在 for 循环中,我再次使用 fgets 来获取输入。问题是,如果您输入的字符串大于 19 个字符,则剩余部分将留在输入缓冲区中,并应分配给后续输入。为了解决这个问题,我在 while 循环中使用了 getchar,它消耗了输入流中所有不必要的字符和换行符。避免使用 fflush,因为它可能会导致此处回答的未定义行为
-fflush(stdin) function does not work
-http://www.geeksforgeeks.org/clearing-the-input-buffer-in-cc/
另请注意,您使用的可变长度数组可能并不总是一个好的选择。旧版本的 c 编译器禁止它们。你在初始化 N 之前先声明了 color[N][20]。那是错误的。
我建议你也看看这个
-C - scanf() vs gets() vs fgets()
由于此引用:
https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm
这将是正确的:
int _tmain(int argc, _TCHAR* argv[])
{
int N, i, radius, diameter, count = 0;
char str[10];
char color[20];
printf("Get the num : ");
scanf_s("%d", &N);
printf("Enter the mesage\n");
//for (i = 0; i<N; i++){
fgets(color, 20, stdin);
//}
//for (i = 0; i<N; i++){
printf("%s", color);
//}
return 0;
}
我将 scanf
更改为 scanf_s
VC++。
使用 scanf 后,您需要清理缓冲区。我建议永远不要使用 scanf,只需使用 fgets 然后将输出转换为数字:
int main(){
int N,i,radius,diameter,count =0;
char str[20];
char color[N][20];
printf("Get the num : ");
char buffer[64];
fgets(buffer, 64, stdin);
N = atoi(buffer); // you need to include stdlib.h
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
}
for(i=0;i<N;i++){
printf("%s",color[i]);
}
return 0;
}
这是我的代码
int main(){
int N,i,radius,diameter,count =0;
char str[20];
char color[N][20];
printf("Get the num : ");
scanf("%d",&N);
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
}
for(i=0;i<N;i++){
printf("%s",color[i]);
}
return 0;
}
给定的输入是:
N = 3
red 50,
50 green,
blue 50
这里的问题是如果 N
为 3,则 for 循环中的 fgets
只执行两次。如果我注释 scanf
语句,则不会出现此问题。谁能解释一下是什么导致了这个问题以及如何解决它?
经过几个小时的摸索,我意识到以下几点:
- 避免使用 scanf。管理缓冲区溢出并不容易。
- 始终尝试使用 fgets 获取用户输入。
在这里试试这个代码:
#include<stdio.h>
#include<stdlib.h>
int main(){
int N,i,radius,diameter,count =0;
char str[20];
printf("Get the num : ");
char buffer[64];
fgets(buffer, 64, stdin);
N = strtoul(buffer,NULL,10);
char color[N][20];
printf("%d\n",sizeof(color));
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
if(color[i][strlen(color[i])-1]=='\n'){
color[i][strlen(color[i])-1]='[=10=]';
}
else{
while((getchar())!='\n');//this is just to prevent an overflow for the size of char arrays
}
}
for(i=0;i<N;i++){
printf("%s\n",color[i]);
}
return 0;
}
请注意,我首先在一个字符数组中输入了一个数字。使用 strtoul(string to unsigned long) 将其转换为数字。现在在 for 循环中,我再次使用 fgets 来获取输入。问题是,如果您输入的字符串大于 19 个字符,则剩余部分将留在输入缓冲区中,并应分配给后续输入。为了解决这个问题,我在 while 循环中使用了 getchar,它消耗了输入流中所有不必要的字符和换行符。避免使用 fflush,因为它可能会导致此处回答的未定义行为
-fflush(stdin) function does not work
-http://www.geeksforgeeks.org/clearing-the-input-buffer-in-cc/
另请注意,您使用的可变长度数组可能并不总是一个好的选择。旧版本的 c 编译器禁止它们。你在初始化 N 之前先声明了 color[N][20]。那是错误的。
我建议你也看看这个
-C - scanf() vs gets() vs fgets()
由于此引用: https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm 这将是正确的:
int _tmain(int argc, _TCHAR* argv[])
{
int N, i, radius, diameter, count = 0;
char str[10];
char color[20];
printf("Get the num : ");
scanf_s("%d", &N);
printf("Enter the mesage\n");
//for (i = 0; i<N; i++){
fgets(color, 20, stdin);
//}
//for (i = 0; i<N; i++){
printf("%s", color);
//}
return 0;
}
我将 scanf
更改为 scanf_s
VC++。
使用 scanf 后,您需要清理缓冲区。我建议永远不要使用 scanf,只需使用 fgets 然后将输出转换为数字:
int main(){
int N,i,radius,diameter,count =0;
char str[20];
char color[N][20];
printf("Get the num : ");
char buffer[64];
fgets(buffer, 64, stdin);
N = atoi(buffer); // you need to include stdlib.h
printf("Enter the mesage\n");
for(i=0;i<N;i++){
fgets(color[i],20,stdin);
}
for(i=0;i<N;i++){
printf("%s",color[i]);
}
return 0;
}