我的一位同学告诉我,使用 scanf 扫描字符串时会使用该语法,但没有限制。我的意思是,您可以使用 scanf 扫描字符串,它仍然会扫描空格。
scanf("%[^\n]s",&string);
最佳答案
scanf( "%[^\n]", string );
将读取所有内容并将其存储到(但不包括)换行符到 string
1。与 s
转换说明符不同,它不会跳过任何前导空格(空格、制表符等)。
正如所写,此代码容易受到缓冲区溢出的影响2;如果 string
的大小可以容纳 10 个字符,而有人输入了 100 个字符,那么这些额外的字符将紧随 string
写入内存,这可能会导致各种困惑。
至少,您需要添加一个字段宽度说明符,例如
scanf( "%10[^\n]", string );
表示“将不超过 10 个字符读入字符串
”。不幸的是,字段宽度必须指定为格式字符串的一部分;与 printf
不同,scanf
不提供将字段宽度指定为参数的方法。
您可以动态构建格式字符串,例如:
char fmt[20];
char string[11] = {0};
sprintf( fmt, "%%%zu[^\n]", sizeof string - 1 );
scanf( fmt, string ); // fmt contains the string "%10[^\n]"
这样您就不必对字段宽度进行硬编码。
或者,您可以完全避免胃灼热,只需使用 fgets
即可:
char string[11];
...
fgets( string, sizeof string, stdin );
语义上的主要区别是,如果有空间,fgets
会将换行符存储到 string
中,所以如果您不想要字符串中的换行符,您必须手动删除它:
char *newline = strchr( string, '\n' );
if ( newline )
*newline = 0; // overwrite newline character with 0 terminator
<小时/>
- 这意味着输入流中会出现一个杂散的换行符,这可能会或可能不会导致下一个输入出现问题。
- 它在功能上或多或少相当于
gets
库函数,正是由于这个原因,该函数已从 C 2011 中删除(请参阅下面 chux 的评论,了解“或更少”部分)。
关于c - C中有这样的语法吗? %[^\n]s,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37117006/