是否可以在gets()
中读取包含scanf()
函数等空格的整个字符串?
我可以使用gets()
函数来完成。
char s[30];
gets(s);
这将读取一行字符。可以在scanf()
吗?
答案 0 :(得分:2)
您可以使用scanf()
读取包含空格的行,但此功能很微妙,使用它非常容易出错。使用%[^\n]
转换说明符,您可以告诉scanf()
匹配字符以形成字符串,不包括'\n'
个字符。如果这样做,则应指定最大字段宽度。此宽度指定要匹配的最大字符数,因此您必须为'\0'
终结符留出空间。
输入流中的第一个字符可能是'\n'
。在这种情况下,scanf()
将返回0
的值,因为在遇到换行符之前没有匹配项。但是,s
中不会存储任何内容,因此您可能会有未定义的行为。为避免这种情况,您可以先使用scanf()
转换说明符调用%*[\n]
,然后丢弃所有前导'\n'
个字符。
读取字符串后,输入流中将有其他字符。至少存在'\n'
,如果用户输入的字符数超过最大字段宽度,则可能包含更多字符。然后,您可能希望丢弃这些额外的字符,以便它们不会干扰进一步的输入。下面的代码包含一个执行此操作的循环。
对scanf()
的第一次调用将消耗输入流中的所有换行符,直到遇到非换行符。虽然我认为对scanf()
的第二次调用应始终是成功的,但最好始终检查scanf()
的返回值(这是成功分配的数量)。我已将此值存储在result
中,并在打印字符串之前检查它。如果scanf()
返回意外结果,则会打印错误消息。
使用fgets()
读取整行更好,更容易。您必须记住fgets()
保留尾随换行符,因此您可能希望将其删除。用户还可能输入的字符数超过缓冲区将存储的字符数,而剩余的字符则保留在输入流中。在提示输入更多内容之前,您可能希望删除这些额外的字符。
同样,您应该检查fgets()
的返回值;此函数返回指向存储缓冲区的第一个元素的指针,或者在发生错误时返回NULL
指针。下面的代码替换字符串中的任何尾随换行符,从输入流中丢弃额外的字符,并仅在fgets()
的调用成功时打印字符串。否则,将打印一条错误消息。
#include <stdio.h>
int main(void)
{
char s[30];
int result;
printf("Please enter a line of input:\n");
scanf("%*[\n]"); // throw away leading '\n' if present
result = scanf("%29[^\n]", s); // match up to 29 characters, excluding '\n'
/* Clear extra characters from input stream */
int c;
while ((c = getchar()) != '\n' && c != EOF)
continue; // discard extra characters
if (result == 1) {
puts(s);
} else {
fprintf(stderr, "EOF reached or error in scanf()\n");
}
printf("Please enter a line of input:\n");
char *ps = fgets(s, 30, stdin); // keeps '\n' character
if (ps) {
while (*ps && *ps != '\n') {
++ps;
}
if (*ps) { // replace '\n' with '\0'
*ps = '\0';
} else {
while ((c = getchar()) != '\n' && c != EOF)
continue; // discard extra characters
}
puts(s);
} else {
fprintf(stderr, "EOF reached or error in fgets()\n");
}
return 0;
}
请注意,这两种获取输入的方法并不完全等效。这里写的scanf()
方法不接受空行(即只包含'\n'
字符的行),但接受由其他空白字符组成的行。 fscanf()
方法将接受一个空行作为输入。
此外,如果忽略前导空白字符是可以接受的,那么遵循Jonathan Leffler在评论中给出的建议只使用scanf()
的一次调用会更简单:
result = scanf(" %29[^\n]", s);
这将忽略前导空格字符,包括换行符。
答案 1 :(得分:1)
请勿使用scanf()
或gets()
功能 - 请改用fgets()
。但对于上述问题,请找到答案。
int main() {
char a[30];
scanf ("%29[^\n]%*c", name);
printf("%s\n", a);
return 0;
}
我也强烈推荐,就像我在开始时告诉他使用fgets()
一样。我们显然不了解这种奇怪的要求。我会用fgets()
来读取这个角色。
fgets(a, size(a), stdin);