我使用 Windows 10 机器和代码块作为 IDE。在代码中,我看到使用空格字符(空格)来输入字符串,例如
scanf(" %[^\n]", s);
Run Code Online (Sandbox Code Playgroud)
这背后的原因是什么?
#include<stdio.h>
#include<string.h>
int main()
{
int t, i, j, temp, len;
char s[1002];
scanf("%d", &t);
while(t--){
scanf(" %[^\n]", s);
len = strlen(s);
for(i = 0, j = (len-1); i < (len/2); i++, j--){
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
printf("%s\n", s);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这个程序中,程序员只是试图替换字符串的组成部分
开头的空格" %[^\n]" 匹配输入中任意数量的空格字符' '、'\t'、'\n'等,并跳过它们
请注意,scanf具体而言,大多数格式说明符设计为跳过空格,因此不需要前导空格,但三个不需要:
`%n` — count of characters processed
`%[…]` — scan set
`%c` — read char.
Run Code Online (Sandbox Code Playgroud)
表达式的第二部分是scan set,并且与本次讨论相关,因为如果调用的输入太长,所写的可能会调用未定义的行为scanf()。
%[^\n]匹配除newline( \n)之外的所有字符,因此将它与终止符一起存储\0到s. 如果输入恰好长于s(在这种情况下 > 1001),则将没有空间用于终止'\0',从而导致char数组没有空终止。这本身不是未定义的行为,但调用len = strlen(s);下一行将是。
因此,考虑到char s[1002];可以容纳的最大输入长度是1001(为 留出空间'\0'),那么更安全的表达式是:
scanf(" %1001[^\n]", s);
Run Code Online (Sandbox Code Playgroud)
它将输入长度限制为以下值%,从而为空终止符的放置留出空间。