找到= strchr(st,'\ n');替换为* find ='\ 0';

时间:2018-10-18 02:58:14

标签: c strchr

我从 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;
}

find = strchr(st, '\n');之后加上*find = '\0';

是出于什么目的?

我搜索了strchr,但发现它是一个奇怪的名字,尽管可以对其功能有所了解。名称strchr是否来自stringcharacter

1 个答案:

答案 0 :(得分:4)

如果字符串中确实存在换行符,则使用find = strchr(s, '\n')及其后的代码将换行fgets()读取并包含在结果字符串中的换行符。通常,您可以使用其他更紧凑的表示法:

s[strcspn(s, "\n")] = '\0';

在编写时没有任何条件代码可见。 (如果没有换行符,则空字节将覆盖现有的空字节。)

总体目标似乎是使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 points out一样,您可以捕获strcspn()的结果,然后确定是否找到换行符,从而决定是否读取到行尾(如果没有则换行到文件尾) EOL之前的EOL)。