繁体   English   中英

C编程语言(scanf)

[英]C programming language (scanf)

我已经使用以下scanf()语句读取了带有空格的字符串。

scanf("%[^\n]", &stringVariableName);

控制字符串[^\\n]是什么意思?

可以这样读取带有空格的字符串吗?

这意味着“阅读任何内容,直到找到'\\ n'”

可以,但是这样做更好:“读取任何内容,直到找到'\\ n',或者读取比我的缓冲区支持更多的字符”

char stringVariableName[256] = {}
if (scanf("%255[^\n]", stringVariableName) == 1)
    ...

编辑:从参数中删除&,然后检查scanf的结果。

格式说明符"%[^\\n]"指示scanf()读取最多但不包括换行符。 从链接的参考页面:

matches a non-empty sequence of character from set of characters. 

If the first character of the set is ^, then all characters not
in the set are matched. If the set begins with ] or ^] then the ]
character is also included into the set.

如果字符串在一行上,则可以使用fgets() ,但是必须将新行删除,因为fgets()会将其写入输出缓冲区。 fgets()还强制程序员指定可以读入缓冲区的最大字符数,从而使缓冲区溢出的可能性较小:

char buffer[1024];
if (fgets(buffer, 1024, stdin))
{
    /* Remove newline. */
    char* nl = strrchr(buffer, '\n');
    if (nl) *nl = '\0';
}

可以指定通过scanf()读取的最大字符数:

scanf("%1023[^\n]", buffer);

但是不可能忘记为fgets()做它,因为编译器会抱怨。 当然,尽管程序员可能会指定错误的大小,但至少他们被迫考虑使用错误的大小。

从技术上讲,这不能很好地定义。

匹配一组预期字符(扫描集)中的非空字符序列。

如果不存在长度修饰符,则相应的参数应为指向字符数组初始元素的指针,该元素的大小应足以接受该序列和一个终止的空字符,该字符将自动添加。

假设stringVariableName的声明类似于char stringVariableName[x]; ,则&stringVariableNamechar (*)[x]; ,而不是char * 类型错误。 该行为是不确定的。 也许巧合的工作,但任何依赖巧合不通过我的定义工作

使用&stringVariableName形成char *的唯一方法是,如果stringVariableNamechar 这意味着字符数组仅足够大以接受终止的空字符。 如果用户在按Enter键之前输入一个或多个字符,则scanf将超出字符数组的末尾写入并调用未定义的行为。 如果用户仅按Enter键,则%[...]指令将失败,甚至不会将'\\0'写入字符数组


现在,一切都说完了,我将假设您的意思是: scanf("%[^\\n]", stringVariableName); 注意省略的“&”号

您确实应该检查返回值!!

%[指令使scanf检索由在[方括号]之间指定的字符组成的字符序列。 集合开头的^表示所需集合包含除方括号之间的字符以外的所有字符。 因此, %[^\\n]告诉scanf读取尽可能多的非'\\n'字符,并将它们存储到相应char *指向的数组中。

'\\n'将不被读取。 这可能会引起问题。 空字段将导致匹配失败。 在这种情况下,有可能没有数据将被复制到您的数组中(甚至没有终止的'\\0'字符)。 由于这个原因(以及其他原因), 您确实需要检查返回值

哪本手册包含有关scanf返回值的信息? scanf手册

从手册页中读取scanf() ...

[匹配指定接受字符集中的非空字符序列; 下一个指针必须是指向char的指针,并且字符串中的所有字符必须有足够的空间,再加上一个终止的空字节。 通常的前导空白跳过被抑制。 字符串由(或不在)特定集合中的字符组成; 该集合由左方括号[字符和右方括号]字符之间的字符定义。 如果开括号后的第一个字符是抑音符(^),则该字符集将排除这些字符。 要在集合中包括右括号,请将其放在开括号或抑扬符之后的第一个字符; 任何其他位置将结束该集合。 连字符-也很特殊; 当放置在其他两个字符之间时,它将所有中间字符添加到集合中。 要包含连字符,请使其成为最后一个方括号之前的最后一个字符。 例如,[^] 0-9-]表示集合“除右括号,零至九和连字符以外的所有内容”。 字符串的结尾是未设置(或带有抑扬符号,输入)字符或字段宽度用尽的字符。

简而言之,[^ \\ n]表示从不是\\n的字符串中读取所有内容,并将其存储在参数列表的匹配指针中。

其他人已经解释了%[^\\n]含义。

不是读取字符串的好方法。 这是一样危险,出了名的不安全gets ,出于同样的原因:它不知道在缓冲区有多大stringVariableName是。

从文件中读取一个完整行的最佳方法是getline ,但并非所有C库都拥有它。 如果不这样做,则应使用fgets ,它知道缓冲区的大小,并且请注意,您可能无法获得完整的行(如果该行对于缓冲区而言太长)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM