%[^\n]
在C中意味着什么?
我在一个程序中看到它,它使用scanf
将多个单词输入转换为字符串变量。我不明白,因为我了解到scanf不能用多个单词。
以下是代码:
#include <stdio.h>
#include <stdlib.h>
int main() {
char line[100];
scanf("%[^\n]",line);
printf("Hello,World\n");
printf("%s",line);
return 0;
}
答案 0 :(得分:8)
[^\n]
是一种正则表达式。
[...]
:它匹配 scanset (由...
给出的一组字符)中的非空字符序列。^
表示扫描集被“否定”:它由补充给出。^\n
:扫描集是除\n
以外的所有字符。此外fscanf
(和scanf
)将读取与格式匹配的最长输入字符序列。
所以scanf("%[^\n]", s);
会读取所有字符,直到您到达\n
(或EOF
)并将其放入s
。在C中读取整行是一种常见的习语。
答案 1 :(得分:2)
scanf("%[^\n]",line);
表示:扫描到\n
或输入密钥。
答案 2 :(得分:2)
#' @rdname recall
#' @importFrom stats complete.cases
#' @export
recall.default <- function(data, reference, relevant = levels(reference)[1],
na.rm = TRUE, ...) {
if (!is.factor(reference) | !is.factor(data))
stop("input data must be a factor")
if (length(unique(c(levels(reference), levels(data)))) != 2)
stop("input data must have the same two levels") # where we see two means 2
if (na.rm) {
cc <- complete.cases(data) & complete.cases(reference)
if (any(!cc)) {
data <- data[cc]
reference <- reference[cc]
}
}
xtab <- table(data, reference)
recall.table(xtab, relevant = relevant)
}
是读取行的一种问题方式。比gets()
更糟。
C将 line 定义为:
文本流是由行组成的有序字符序列,每行包含零个或多个字符以及一个换行符。最后一行是否需要终止换行符是实现定义的。
scanf("%[^\n]",line);
具有说明符scanf("%[^\n]", line)
。它扫描不限数量的与 scan-set "%[^\n]"
匹配的字符。如果未读取任何内容,说明符将失败,并且^\n
会返回scanf()
不变。如果至少读取了一个,则将读取并保存所有匹配项。会添加空字符。
扫描集line
表示不是 的所有字符(由于^\n
)'^'
。
'\n'
未读
'\n'
无法读取换行符 scanf("%[^\n]",....
。它保留在'\n'
中。整个 line 都不会被读取。
缓冲区溢出
以下内容导致未定义的行为(UB)应该被读取的字符超过99个。
stdin
空行不执行任何操作
当该行仅包含char line[100];
scanf("%[^\n]",line); // buffer overflow possible
时,"\n"
将返回scanf("%[^\n]",line);
,而无需设置0
。如果后续代码使用未初始化的line[]
,则很容易导致未定义的行为。 line[]
保留在'\n'
中。
无法检查返回值
stdin
假定输入成功。更好的代码将检查scanf("%[^\n]",line);
返回值。
推荐
请勿使用scanf()
,而应使用scanf()
来读取输入的行。
fgets()
#define EXPECTED_INPUT_LENGTH_MAX 49
char line[EXPECTED_INPUT_LENGTH_MAX + 1 + 1 + 1];
// \n \0 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] = '\0';
}
if (len > EXPECTED_INPUT_LENGTH_MAX) {
// Handle error
// Usually includes reading rest of line if \n not found.
}
方法也有其局限性。例如(嵌入空字符)。
处理可能有害的用户输入具有挑战性。
答案 3 :(得分:1)
scanf("%[^\n]",line);
将读取用户输入,直到按下enter或添加换行符(\n
)并将其存储到名为line的变量中。