scanf("%[^\n]s",str1);
scanf("%[^\n]s",str2);
当我将它用于多个数组时,它无法正常工作。 我身边有什么错误,或者我们不能将它用于多个阵列吗?
答案 0 :(得分:0)
可能:
scanf(" %[^\n]",str1);
scanf(" %[^\n]",str2);
请注意前面的空格,强制scanf()
跳过前导空格(并且第一次调用未读取的换行计为空白字符)。
但是:此代码可能存在未定义的行为,如果输入的行长于str1
或str2
,则会导致缓冲区溢出可以存储。 你永远不应该写这样的代码。
使用scanf()
,您可以使用字段宽度来限制读取的字符数量:
str1[256];
scanf(" %255[^\n]", str1); // one less because a 0 character must be appended
更好的方法是使用专用于阅读行的功能:fgets()
:
#include <stdio.h> // for fgets()
#include <string.h> // for strcspn()
#define BUFFERSIZE 256
// [...]
str1[BUFFERSIZE];
int main(void)
{
// [...]
// no need to subtract 1 here, `fgets()` accounts for the trailing `0`:
if (!fgets(str1, BUFFERSIZE, stdin))
{
// read error, e.g. print error message
exit(1);
}
// fgets includes the newline if there was one, so strip it:
str1[strcspn(str1, "\n")] = 0;
// [...]
}
答案 1 :(得分:0)
在您描述时调用scanf()
...
scanf("%[^\n]s",str1);
将标准输入中的字符读入由str1
指定的字符数组,不跳过前导空格,但不包括第一个换行符。 换行符(如果有)仍然未读。如果导致零个字符传输到数组,则会发生匹配失败(因此您不能依赖正在写入的字符串终结符)。否则,scanf()
会尝试读取(并忽略)'s'
个字符,但这必须始终产生匹配的失败;不会消耗任何角色。
如果在尝试匹配%[
指令时发生不可避免的匹配失败,则该函数将返回0;如果尝试匹配&#39; s,则该函数将返回1。如果在从标准输入读取零个字符时,或者如果发生I / O错误,它将返回EOF
。
如果您尝试使用相同的格式再次阅读,则第二次读取必须始终在%[
指令中输入失败或匹配失败,因为如果有更多字符可用,则下一个必须是换行符。
通常,通过fgets()
更好地逐行阅读。如果你必须通过scanf()
来做,那么你应该按照这些方式做点什么:
char str1[100];
char c;
int result;
// Note use of a field width to protect from buffer overrun:
result = scanf("%99[^\n]%c", str1, &c);
switch (result) {
case EOF: /* no characters available or I/O error */
/* ... handle error ... */
break;
case 0:
/* the first character was a newline */
result = getchar(); // consume the newline
assert(result == '\n');
str1[0] = '\0'; // ensure the (empty) string is terminated
break;
case 1:
/* should happen only at end of file or on I/O error */
assert(feof(stdin) || ferror(stdin));
/* ... any special handling for this being the last line of the file ... */
break;
case 2:
if (c != `\n`) {
/* the line was longer than 99 characters (excluding the newline) */
/* ... recover from overlength line ... */
}
break;
default:
/* should never happen */
/* ... handle unexpected result ... */
}
即使没有填写一些细节,这也非常冗长,所以我建议你把它分解成自己的功能。另请注意,fgets()
使其简化 er ,但它仍然有其复杂性。特别是,您仍需要注意超长行,fgets()
包括字符串中的尾部换行符(如果有的话)。