我读了C Primer Plus中的一段代码,并努力理解*find = '\0';
#include <stdio.h>
#include <string.h>
char *s_gets(char *st, int n);
struct book {
char title[40];
char author[40];
float value;
}
int main(void) {
...
}
char *s_gets(char *st, int n) {
char *ret_val;
char *find;
ret_val = fgets(st, n, stdin);
if (ret_val) {
find = strchr(st, '\n'); //look for newline
if (find) // if address is not null
*find = '\0'; //place a null character there
else
while (getchar() != '\n')
continue; //dispose rest of line
}
return ret_val;
}
Run Code Online (Sandbox Code Playgroud)
出于什么目的应该find = strchr(st, '\n');遵循*find = '\0';
我搜索了一下strchr,但发现它的名字很奇怪,尽管可以了解它的功能。名字是strchr从来的吗stringcharacter?
使用的代码find = strchr(s, \'\\n\')和后面的内容会改变读取的换行符fgets()确实有换行符,则使用和后面的代码将删除结果字符串中通常,您可以使用替代的、更紧凑的表示法:
s[strcspn(s, "\\n")] = \'\\0\';\nRun Code Online (Sandbox Code Playgroud)\n\n这是在没有任何可见条件代码的情况下编写的。(如果没有换行符,空字节将覆盖现有的空字节。)
\n\n总体目标似乎是使s_gets()行为更像一个古董、危险且不再标准的函数,gets()它读取并包含换行符,但在结果中不包含换行符。这gets()函数还有其他设计缺陷,使其成为一个被遗忘的函数 \xe2\x80\x94 永远不要使用它!
显示的代码还检测何时没有读取换行符,然后进入危险循环以读取该行的其余部分。循环应该是:
\n\nelse\n{\n int c;\n while ((c = getchar()) != EOF && c != \'\\n\')\n ;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n检测EOF很重要;并非所有文件都以换行符结尾。可靠地检测 EOF 也很重要,这意味着该代码必须使用int c(而原始有缺陷的循环可以避免使用像 之类的变量c)。如果此代码不小心使用char c而不是int c,它可能无法完全检测到 EOF(如果 plainchar是无符号类型),或者当正在读取的数据包含值为 0xFF 的字节(如果 plainchar是有符号类型)时,它可能会给出 EOF 误报。类型)。
请注意,在此代码中不能直接使用strcspn()所示的选项,因为这样您就无法检测数据中是否有换行符;您只知道调用后数据中没有换行符。正如Antti Haapala 指出的那样,您可以捕获结果strcspn(),然后决定是否找到换行符,从而决定是否读取到行尾(如果 EOF 之前没有 EOL,则读取到文件末尾)。