fgets() 没有扫描我想要的字符串数
fgets() not scanning the number of strings I want
我有一个句子数组,我想先用fgets()
扫描它们,然后一个一个打印出来。这是程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char *argv[]) {
char sentence[100][100]; /* 100 sentences with at most 100 characters*/
int n,i,j;
scanf("%d",&n); /* number of sentences*/
for (i=0;i<n;i++) {
fgets(sentence[i],100,stdin);
}
printf("****************************");
for (i=0;i<n;i++) {
for(j=0;j<strlen(sentence[i]);j++) {
putchar(sentence[i][j]);
}
}
return 0;
}
问题是这只扫描了n-1个句子。这是为什么?
另一个奇怪的事情是,在打印星号之后,它在我没有告诉它这样做的情况下开始在一个新行打印。
您是否阅读了 fgets 的手册页?
fgets() 从流中读入最多小于 size 个字符,并将它们存储到 s 指向的缓冲区中。在 EOF 或换行符后停止阅读。如果读取到换行符,则将其存储到缓冲区中。终止空字节 ('\0') 存储在缓冲区中的最后一个字符之后。
因此,正如 chux 所指出的那样,您的代码应该是:
fgets(sentence[i],sizeof sentence[i],stdin);
假设输入是
3
abc
def
ghi
扫描n后光标停留在第一行第3
号后
你可以在%d
后面加一个space,比如scanf("%d ", &n);
,把光标移动到下一行。 (这假设第一句不以 spaces 开头)。
取决于你的环境是否是(Windows / Unix),以及你是否希望每个字符串都保留行尾字符,你需要将缓冲区大小增加到:
- 101 - 对于 Unix 行尾,对于 100 个字符长的句子,您可以丢弃行尾字符
- 102 - 对于 Windows 行结束,您可以丢弃 100 个字符长的句子的行尾字符
- 102 - 用于 Unix 行结束并且您想为所有句子保留行结束字符
- 103 - 对于 Windows 行结束并且您想为所有句子保留行尾字符
例如,如果您错误地将 101 用于 Windows,则对于以下输入
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
输出将是:
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
(有些空行)
两种情况都将由一个概念解决,fgets()
将newline
视为输入的一部分。
问题 1:
您在输入缓冲区中留下了一个 newline
(由于在第一次输入后按下 ENTER 键),它被紧接的下一个 fgets()
.
拾取
解决问题 1:
使用
scanf("%d%*c",&n); //simple solution
或
scanf("%d",&n);
while (getchar() != '\n'); //eat up anything upto newline
清除结尾的换行符。
问题 2:
fgets()
根据输入扫描并存储 newline
。如果您不希望换行符作为输入的一部分,您必须手动检查并删除它。
手册页中的相关引用:
[...] If a newline is read, it is stored into the buffer. [...]
解决问题 2:
sentence[strcspn(sentence, "\r\n")] = 0;
感谢@chux, more about this here
我有一个句子数组,我想先用fgets()
扫描它们,然后一个一个打印出来。这是程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char *argv[]) {
char sentence[100][100]; /* 100 sentences with at most 100 characters*/
int n,i,j;
scanf("%d",&n); /* number of sentences*/
for (i=0;i<n;i++) {
fgets(sentence[i],100,stdin);
}
printf("****************************");
for (i=0;i<n;i++) {
for(j=0;j<strlen(sentence[i]);j++) {
putchar(sentence[i][j]);
}
}
return 0;
}
问题是这只扫描了n-1个句子。这是为什么?
另一个奇怪的事情是,在打印星号之后,它在我没有告诉它这样做的情况下开始在一个新行打印。
您是否阅读了 fgets 的手册页?
fgets() 从流中读入最多小于 size 个字符,并将它们存储到 s 指向的缓冲区中。在 EOF 或换行符后停止阅读。如果读取到换行符,则将其存储到缓冲区中。终止空字节 ('\0') 存储在缓冲区中的最后一个字符之后。
因此,正如 chux 所指出的那样,您的代码应该是:
fgets(sentence[i],sizeof sentence[i],stdin);
假设输入是
3 abc def ghi
扫描n后光标停留在第一行第3
号后
你可以在%d
后面加一个space,比如scanf("%d ", &n);
,把光标移动到下一行。 (这假设第一句不以 spaces 开头)。
取决于你的环境是否是(Windows / Unix),以及你是否希望每个字符串都保留行尾字符,你需要将缓冲区大小增加到:
- 101 - 对于 Unix 行尾,对于 100 个字符长的句子,您可以丢弃行尾字符
- 102 - 对于 Windows 行结束,您可以丢弃 100 个字符长的句子的行尾字符
- 102 - 用于 Unix 行结束并且您想为所有句子保留行结束字符
- 103 - 对于 Windows 行结束并且您想为所有句子保留行尾字符
例如,如果您错误地将 101 用于 Windows,则对于以下输入
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
输出将是:
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
(有些空行)
两种情况都将由一个概念解决,fgets()
将newline
视为输入的一部分。
问题 1:
您在输入缓冲区中留下了一个 newline
(由于在第一次输入后按下 ENTER 键),它被紧接的下一个 fgets()
.
解决问题 1:
使用
scanf("%d%*c",&n); //simple solution
或
scanf("%d",&n);
while (getchar() != '\n'); //eat up anything upto newline
清除结尾的换行符。
问题 2:
fgets()
根据输入扫描并存储 newline
。如果您不希望换行符作为输入的一部分,您必须手动检查并删除它。
手册页中的相关引用:
[...] If a newline is read, it is stored into the buffer. [...]
解决问题 2:
sentence[strcspn(sentence, "\r\n")] = 0;
感谢@chux, more about this here