Fox*_*xen 3 c scanf c89 format-specifiers ansi-c
我正在使用 scanf 从 sdin 读取字符串:
scanf("%[^\n]s", msg);
Run Code Online (Sandbox Code Playgroud)
%[^\n]s读取直到找到新行字符。这在 ANSI-C 中合法吗?
由于多种原因,您不应使用此格式:
in不是转换说明符的一部分,它是一个普通字符,当当前字符是换行符或文件末尾时,将从行读取的字符之后尝试匹配s。您应该删除."%[^\n]s"scanfs
scanf("%[^\n]", msg);将失败并返回 0,msg如果用户使用空输入行按 Enter 键,则保持不变。
scanf("%[^\n]", msg);对于任何足够长的输入行都会导致缓冲区溢出。msg应在%和之间指定要存储到 by 指向的数组中的最大字符数,如下所示[:
char buf[100];
if (scanf("%99[^\n]", msg) == 1) {
// msg contains the input line, up to 99 characters
// the remainder if this input line is still in stdin
// so is the newline
}
Run Code Online (Sandbox Code Playgroud)
scanf("%99[^\n]", msg);如果在换行符之前键入了超过 99 个字符,则不会消耗换行符并在输入流中留下额外的字符,这可能不是预期的行为。
这是一个更安全的替代方案:
// read a line of input, discard extra characters and the trailing newline
int mygets(char *dest, size_t size) {
int c;
size_t i = 0;
while ((c = getchar()) != EOF && c != '\n') {
if (i + 1 < size) {
dest[i++] = c;
}
}
if (size > 0)
dest[i] = '\0';
if (c == EOF && (i == 0 || ferror(stdin)))
return EOF;
else
return (int)i;
}
Run Code Online (Sandbox Code Playgroud)
格式说明符 %[^\n]s 在 C89 中合法吗?
是的,它是“合法的”,因为行为将被定义。
将%[^\n]扫描除换行符之外的任何内容。s将扫描s. s永远不会匹配,因为缓冲区中会有换行符,或者出现错误情况。尽管如此,它仍然是“有效的”。