为什么fgets没有输入第一个值?
我正在编写一个程序来快速编写我的html文件。 当我来写我的页面内容时,我遇到了问题。
#include int main() { int track; int question_no; printf("\nHow many questions?\t"); scanf("%d",&question_no); char question[question_no][100]; for(track=1;track<=question_no;track++) { printf("\n%d. ",track); printf("\nQuestion number %d.\t",track); fgets(question[track-1],sizeof(question[track-1]),stdin); printf("\n\n\tQ%d. %s ",track,question[track-1]); } }
在这个程序中,我正在写一些问题及其答案(在html文件中)。 当我测试运行这个程序时,我将question_no
的值输入到3.但是当我输入我的第一个问题时,它没有question[0]
,因此第一个问题没有输出。 其余的问题输入没有问题。
我在stackoverflow上搜索了一些问题,发现fgets()
查找最后的\0
字符,并且\0
停止它。
我还发现我应该使用缓冲区通过fgets()
输入,所以我使用: setvbuf
和setbuf
但也没有用(我可能编码错了)。 在我的第一个和最后一个(以及) scanf
语句之后我也使用了fflush(stdin)
从stdin中删除任何\0
字符,但这也没有用。
有没有办法接受fgets()
的第一个输入?
我现在正在使用stdin和stdout。 我不访问,读取或写入任何文件。
也可以使用fgets
作为第一个提示。 你也应该malloc
你的数组,因为你不知道它在编译时会有多长。
#include #include #define BUFSIZE 8 int main() { int track, i; int question_no; char buffer[BUFSIZE], **question; printf("\nHow many questions?\t"); fgets(buffer, BUFSIZE, stdin); question_no = strtol(buffer, NULL, 10); question = malloc(question_no * sizeof (char*)); if (question == NULL) { return EXIT_FAILURE; } for (i = 0; i < question_no; ++i) { question[i] = malloc(100 * sizeof (char)); if (question[i] == NULL) { return EXIT_FAILURE; } } for(track=1;track<=question_no;track++) { printf("\n%d. ",track); printf("\nQuestion number %d.\t",track); fgets(question[track-1],100,stdin); printf("\n\n\tQ%d. %s ",track,question[track-1]); } for (i = 0; i < question_no; ++i) free(question[i]); free(question); return EXIT_SUCCESS; }
C中的2D数组
type
的2D数组可以由指向type
的指针数组表示,或者等效地type**
(指向type**
指针的指针)。 这需要两个步骤。
使用char **question
作为示例:
第一步是分配一个char*
数组。 malloc
返回指向已分配内存开头的指针,如果失败则返回NULL
。 所以检查question
是否为NULL
。
其次是让每个char*
指向自己的char
数组。 因此for
循环为每个question
元素分配一个大小为100 char
的数组。 同样,这些malloc
的每一个都可以返回NULL
因此您应该检查它。
每个malloc
应该是free
因此当您使用完已分配的内存后,应该反向执行该过程。
malloc参考
与strtol
long int strtol(const char *str, char **endptr, int base);
strtol
返回一个long int
(在上面的代码中将其转换为int
)。 它将str
分为三个部分:
- 字符串数字内容之前的任何空格
- 它识别为数字的部分,它将尝试转换
- 其余的字符串
如果endptr
不是NULL
,它将指向第3部分,因此您知道strtol
完成的位置。 你可以像这样使用它:
#include #include int main() { char * endptr = NULL, *str = " 123some more stuff"; int number = strtol(str, &endptr, 10); printf("number interpreted as %d\n" "rest of string: %s\n", number, endptr); return EXIT_SUCCESS; }
输出:
number interpreted as 123 rest of string: some more stuff
strtol参考
这是因为scanf()在输入流中留下了前一个换行符。 请注意,如果遇到换行符,fgets()也会停止。
fgets()从流中读取最多一个小于大小的字符,并将它们存储到s指向的缓冲区中。 阅读在EOF或换行后停止。 如果读取换行符,则将其存储到缓冲区中
不要混合fgets()和scanf()。 一个简单的解决方案是在scanf()之后立即使用getchar(),以便通过scanf()消耗输入流中留下的换行符。
根据文档 ,
fgets()函数应从流中读取字节到s指向的数组,直到读取n-1个字节,或者读取
并将其传送给s,或者遇到文件结束条件
如果是scanf("%d",&question_no);
缓冲区中会留下一个换行符,并由其读取
fgets(question[track-1],sizeof(question[track-1]),stdin);
它退出了。
为了冲洗你应该做的缓冲区 ,
while((c = getchar()) != '\n' && c != EOF) /* discard */ ;
清除缓冲区中的额外字符