Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C程序设计语言(scanf)_C_Whitespace_Scanf - Fatal编程技术网

C程序设计语言(scanf)

C程序设计语言(scanf),c,whitespace,scanf,C,Whitespace,Scanf,我使用下面的scanf语句读取了带有空格的字符串 scanf("%[^\n]", &stringVariableName); 控制字符串[^\n]的含义是什么 这样读取带空格的字符串可以吗?格式说明符%[^\n]指示最多读取但不包括换行符。从链接的参考页: matches a non-empty sequence of character from set of characters. If the first character of the set is ^, then all

我使用下面的scanf语句读取了带有空格的字符串

scanf("%[^\n]", &stringVariableName);
控制字符串[^\n]的含义是什么

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

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

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. 可以指定通过scanf读取的最大字符数:


但是不可能忘记对fgets执行此操作,因为编译器会抱怨。当然,程序员可以指定错误的大小,但至少他们不得不考虑它。

< P>从Snff…/P>的页面中读取。 [匹配源代码中的非空字符序列] 指定的接受字符集;下一个指针必须是 指向char的指针,并且必须有足够的空间容纳所有字符 在字符串中,加上一个终止的空字节 前导空格被抑制。字符串由 特定集合中的字符或不在特定集合中的字符;该集合由 开括号[字符和闭括号]之间的字符 字符。如果第一个字符 在开放括号后面是一个扬抑符^。包括一个闭合符 在集合中使用括号,使其成为打开括号后的第一个字符 或回旋;任何其他位置都将结束集合。连字符 字符-也是特殊的;当放置在其他两个字符之间时 字符,它将所有中间字符添加到集合中。到 包括连字符,使其成为最终关闭前的最后一个字符 括号。例如,[^]0-9-]表示设置除 关闭括号,从零到九,以及连字符。字符串以 不在或中的字符的外观,带有 扬抑符,设置中或字段宽度用完时


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

这表示读取任何内容,直到找到“\n”

这是可以的,但是最好在找到“\n”之前读取任何内容,或者读取比我的缓冲区支持更多的字符

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

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

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

这不是读取字符串的好方法。这和众所周知的不安全一样危险,原因也是一样的:它不知道stringVariableName的缓冲区有多大


从文件中读取一整行的最好方法是,但并非所有C库都有。如果不这样做,您应该使用,它知道缓冲区有多大,并且要注意,如果缓冲区的行太长,您可能无法获得完整的行。

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

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

如果不存在l长度修饰符,则应使用相应的参数 是指向足够大的字符数组的初始元素的指针 接受序列和终止的空字符,该字符将 自动添加

假设stringVariableName的声明类似于char stringVariableName[x];,然后&stringVariableName是一个char*[x];,不是字符*。字体不对。这种行为没有定义。这可能是巧合,但根据我的定义,任何依赖巧合的东西都不起作用

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

现在,说了这么多,我假设您的意思是:scanf%[^\n],stringVariableName;注意省略的符号和

你真的应该检查返回值

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

“\n”将保持未读状态。这可能会导致问题。空字段将导致匹配失败。在这种情况下,可能不会将任何数据复制到数组中,甚至不会将终止的“\0”字符复制到数组中。出于此原因和其他原因,您确实需要检查返回值

哪本手册包含有关scanf?返回值的信息
停止使用FGET。别忘了阅读你在流中留下的新行。此外,您可能希望指定最大长度以避免缓冲区溢出。Bluepixy是正确的。scanf是一个巨大的安全风险。对我来说,scanf是一个痛苦不只是你一个人。@ncmathsadist不。scanf根本不是安全风险。风险在于程序员错误地使用了它,完全忽略了手册,带有一些过度膨胀的自我意识。。。如果阅读本页的任何人花时间耐心阅读手册,他们就会知道该代码中另外两个几乎未知的问题,以及如何避免这些问题。scanf是否使用正则表达式?所以我不知道。@cHao,它不是一个真正的正则表达式。%[…]格式表面上类似于regexp语法的一部分,但它不是一个正则表达式。buffer[strcspnbuffer,\n]='\0';。。。此外,为了正确使用格式规范中变量的大小,“+1”。@JonathanLeffler不幸的是,字段宽度似乎是唯一的焦点。此代码还有两个其他问题。我不知道是否有人会发现它们…@unfinedbehaviour:Address of array;测试scanf的返回值?是的,你必须去那里…我想这是正确的点,小跑我的。但根据我的经验,当某人的代码需要帮助时,列出其代码中的所有问题是一种让他们停止关注的好方法。如果他们真的要求进行代码审查,那就不同了。scanf非常有用而且功能强大,而且它和C中的所有其他东西一样工作,如果你知道自己在做什么,那么就去做吧。如果你不清楚这个函数是如何工作的,那么在使用它之前先阅读一下文档@undefined behaviour我可以想象一个编译器重写char buf[N]。。。getsbuf;作为fgetsbuf,N,stdin;但据我所知,在生产使用中没有编译器真正做到这一点。你就是这么想的吗?否则,请解释。realloc如何知道从旧对象复制到新对象的字节数?@undefinedbehaviour:realloc必须设计为知道复制的空间数;内存分配器负责知道分配了多少空间。GET的情况不同;通常,它无法知道传递给gets的函数的数组参数的大小。
scanf("%1023[^\n]", buffer);
char stringVariableName[256] = {}
if (scanf("%255[^\n]", stringVariableName) == 1)
    ...