find = strchr(st, '\n');替换为 *find = '\0';
find = strchr(st, '\n'); replaced with *find = '\0';
我从 C Primer Plus 中阅读了一段代码,并努力理解 *find = '[=11=]';
#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 = '[=10=]'; //place a null character there
else
while (getchar() != '\n')
continue; //dispose rest of line
}
return ret_val;
}
为什么 find = strchr(st, '\n');
后跟 *find = '[=11=]';
我搜索了 strchr
,但发现它的名字很奇怪,但可以了解它的功能。 strchr
这个名字来自 stringcharacter
吗?
如果字符串中确实有换行符,使用 find = strchr(s, '\n')
的代码和后面的代码将删除由 fgets()
读取并包含在结果字符串中的换行符。通常,您可以使用另一种更紧凑的表示法:
s[strcspn(s, "\n")] = '[=10=]';
这是在没有任何条件代码可见的情况下编写的。 (如果没有换行符,空字节将覆盖现有的空字节。)
整体 objective 似乎是为了让 s_gets()
表现得更像 antique, dangerous and no longer standard function, gets()
,它读取并包含一个换行符,但不在结果中包含换行符. gets()
函数还有其他设计缺陷,这使得它成为一个被遗忘的函数——永远不要使用它!
显示的代码还会检测何时没有读取换行符,然后进入危险循环以读取该行的其余部分。循环应该是:
else
{
int c;
while ((c = getchar()) != EOF && c != '\n')
;
}
检测EOF很重要;并非所有文件都以换行符结尾。可靠地检测 EOF 也很重要,这意味着此代码必须使用 int c
(而原始的有缺陷的循环可以避免使用像 c
这样的变量)。如果此代码不小心使用 char c
而不是 int c
,它可能无法完全检测到 EOF(如果普通 char
是无符号类型)或者当正在读取的数据包含一个值为 0xFF 的字节(如果普通 char
是有符号类型)。
请注意,如图所示直接使用 strcspn()
不是此代码中的选项,因为这样您就无法检测数据中是否有换行符;您只知道调用后数据中没有换行符。作为 Antti Haapala ,您可以捕获 strcspn()
的结果,然后决定是否找到换行符并因此决定是否读取到行尾(如果在 EOF 之前没有 EOL,则读取到文件末尾) .
我从 C Primer Plus 中阅读了一段代码,并努力理解 *find = '[=11=]';
#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 = '[=10=]'; //place a null character there
else
while (getchar() != '\n')
continue; //dispose rest of line
}
return ret_val;
}
为什么 find = strchr(st, '\n');
后跟 *find = '[=11=]';
我搜索了 strchr
,但发现它的名字很奇怪,但可以了解它的功能。 strchr
这个名字来自 stringcharacter
吗?
如果字符串中确实有换行符,使用 find = strchr(s, '\n')
的代码和后面的代码将删除由 fgets()
读取并包含在结果字符串中的换行符。通常,您可以使用另一种更紧凑的表示法:
s[strcspn(s, "\n")] = '[=10=]';
这是在没有任何条件代码可见的情况下编写的。 (如果没有换行符,空字节将覆盖现有的空字节。)
整体 objective 似乎是为了让 s_gets()
表现得更像 antique, dangerous and no longer standard function, gets()
,它读取并包含一个换行符,但不在结果中包含换行符. gets()
函数还有其他设计缺陷,这使得它成为一个被遗忘的函数——永远不要使用它!
显示的代码还会检测何时没有读取换行符,然后进入危险循环以读取该行的其余部分。循环应该是:
else
{
int c;
while ((c = getchar()) != EOF && c != '\n')
;
}
检测EOF很重要;并非所有文件都以换行符结尾。可靠地检测 EOF 也很重要,这意味着此代码必须使用 int c
(而原始的有缺陷的循环可以避免使用像 c
这样的变量)。如果此代码不小心使用 char c
而不是 int c
,它可能无法完全检测到 EOF(如果普通 char
是无符号类型)或者当正在读取的数据包含一个值为 0xFF 的字节(如果普通 char
是有符号类型)。
请注意,如图所示直接使用 strcspn()
不是此代码中的选项,因为这样您就无法检测数据中是否有换行符;您只知道调用后数据中没有换行符。作为 Antti Haapala strcspn()
的结果,然后决定是否找到换行符并因此决定是否读取到行尾(如果在 EOF 之前没有 EOL,则读取到文件末尾) .