C语言 %[^\n] 在 C 中是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39431924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does %[^\n] mean in C?
提问by Salman Sadi
What does %[^\n]mean in C?
I saw it in a program which uses scanffor taking multiple word input into a string variable. I don't understand though because I learned that scanf can't take multiple words.
%[^\n]在 C中是什么意思?我在一个scanf用于将多个单词输入输入字符串变量的程序中看到了它。我不明白,因为我了解到 scanf 不能使用多个单词。
Here is the code:
这是代码:
#include <stdio.h>
#include <stdlib.h>
int main() {
char line[100];
scanf("%[^\n]",line);
printf("Hello,World\n");
printf("%s",line);
return 0;
}
回答by md5
[^\n]is a kind of regular expression.
[^\n]是一种正则表达式。
[...]: it matches a nonempty sequence of characters from the scanset(a set of characters given by...).^means that the scanset is "negated": it is given by its complement.^\n: the scanset is all characters except\n.
[...]: 它匹配来自扫描集的非空字符序列(由 给出的一组字符...)。^意味着扫描集是“否定的”:它由它的补集给出。^\n: 扫描集是除\n.
Furthermore fscanf(and scanf) will read the longest sequence of input characters matching the format.
此外fscanf(and scanf) 将读取与格式匹配的最长输入字符序列。
So scanf("%[^\n]", s);will read all characters until you reach \n(or EOF) and put them in s. It is a common idiom to read a whole line in C.
因此scanf("%[^\n]", s);将读取所有字符,直到您到达\n(或EOF) 并将它们放入s. 在 C 中阅读整行是一种常见的习惯用法。
See also §7.21.6.2 The fscanf function.
另请参阅第7.21.6.2 节 fscanf 函数。
回答by vitaly-t
scanf("%[^\n]",line);
means: scan till \nor an enter key.
意思是:扫描至\n或回车键。
回答by Bill Wang
scanf("%[^\n]",line);
Will read user input until enter is pressed or a newline character is added (\n) and store it into a variable named line.
将读取用户输入,直到按下 Enter 或添加换行符 ( \n) 并将其存储到名为 line 的变量中。
回答by chux - Reinstate Monica
scanf("%[^\n]",line);is a problematicway to read a line. It worse than gets().
scanf("%[^\n]",line);是一种有问题的方式来阅读一行。它比gets().
C defines lineas:
C 将线定义为:
A text stream is an ordered sequence of characters composed into lines, each line consisting of zero or more characters plus a terminating new-line character. Whether the last line requires a terminating new-line character is implementation-defined.
文本流是由字符组成的有序序列lines,每行由零个或多个字符加上终止的换行符组成。最后一行是否需要终止换行符是实现定义的。
The scanf("%[^\n]", line)has the specifier "%[^\n]". It scans for unlimited number of characters that match the scan-set^\n. If none are read, the specifier fails and scanf()returns with lineunaltered. If at least one is read, all matching are read and saved. A null characteris appended.
在scanf("%[^\n]", line)有符"%[^\n]"。它扫描与scan-set匹配的无限数量的字符^\n。如果没有读取,说明符失败并scanf()返回line原样。如果至少读取了一个,则读取并保存所有匹配项。附加一个空字符。
The scan-set ^\nimplies all character that are not(due to the '^') '\n'.
扫描集^\n意味着所有不是(由于'^') 的字符'\n'。
'\n'is not read
'\n'未读
scanf("%[^\n]",....fails to read a new line chracter'\n'. It remains in stdin. The entire lineis not read.
scanf("%[^\n]",....无法读取新的换行符'\n'。它保留在stdin. 未读取整行。
Buffer overflow
缓冲区溢出
The below leads to undefined behavior(UB) should more than 99 characters get read.
如果读取超过 99 个字符,以下会导致未定义行为(UB)。
char line[100];
scanf("%[^\n]",line); // buffer overflow possible
Does nothing on empty line
在空行上什么都不做
When the line consists of only "\n", scanf("%[^\n]",line);returns a 0without setting line[]. This can readily lead to undeifned bevaiorshould subsequent code use an uninitialized line[]. The '\n'remains in stdin.
当该行只包含 时"\n",scanf("%[^\n]",line);返回0没有设置的line[]。这可以很容易导致undeifned bevaior应该后面的代码使用未初始化line[]。该'\n'遗骸stdin。
Failure to check the return value
检查返回值失败
scanf("%[^\n]",line);assumes input succeeded. Better code would check the scanf()return value.
scanf("%[^\n]",line);假设输入成功。更好的代码会检查scanf()返回值。
Recommendation
推荐
Do not use scanf()and instead use fgets()to read a lineof input.
不要使用scanf(),而是用于fgets()读取一行输入。
#define EXPECTED_INPUT_LENGTH_MAX 49
char line[EXPECTED_INPUT_LENGTH_MAX + 1 + 1 + 1];
// \n ##代码## extra to detect overly long lines
if (fgets(line, sizeof line, stdin)) {
size_t len = strlen(line);
// Lop off potential trailing \n if desired.
if (len > 0 && line[len-1] == '\n') {
line[--len] = '##代码##';
}
if (len > EXPECTED_INPUT_LENGTH_MAX) {
// Handle error
// Usually includes reading rest of line if \n not found.
}
The fgets()approach has it limitations too. e.g. (embedded null chracters).
该fgets()方法也有其局限性。例如(嵌入空字符)。
Handling user input, possible hostile, is challenging.
处理可能具有敌意的用户输入具有挑战性。

