find = strchr (st, '\ n');заменено на * find = '\ 0'; - PullRequest
0 голосов
/ 18 октября 2018

Я прочитал фрагмент кода из 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 голосов
/ 18 октября 2018

Код, использующий find = strchr(s, '\n') и последующие, закрывает новую строку, прочитанную fgets() и включенную в строку результата, если в строке действительно есть новая строка.Часто вы можете использовать альтернативную, более компактную запись:

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

, написанную без видимого условного кода.(Если нет новой строки, нулевой байт перезаписывает существующий нулевой байт.)

Общая цель, по-видимому, состоит в том, чтобы заставить s_gets() вести себя как античная, опасная и более не стандартная функция, gets(), который читает до и включая перевод строки, но не включает перевод строки в результат.Функция gets() имеет и другие недостатки дизайна, которые делают ее функцией, которую нужно забыть - никогда не используйте ее!

Показанный код также обнаруживает, когда не было прочитано ни одной новой строки, а затем переходит в опасный цикл для чтения остальной частилиния.Цикл должен быть:

else
{
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        ;
}

Важно обнаружить EOF;не все файлы заканчиваются символом новой строки.Также важно надежно обнаруживать EOF, что означает, что этот код должен использовать int c (тогда как исходный некорректный цикл мог бы избежать использования такой переменной, как c).Если этот код небрежно использовал char c вместо int c, он может либо вообще не обнаружить EOF (если обычный char тип без знака), либо дать ложное срабатывание для EOF, когда читаемые данные содержат байтсо значением 0xFF (если обычный char является типом со знаком).

Обратите внимание, что использование strcspn() напрямую, как показано, не является вариантом в этом коде, потому что тогда вы не сможете определить, была ли новая строка вданные;Вы просто знаете, что в данных после вызова нет новой строки.Поскольку Антти Хаапала указывает на , вы можете зафиксировать результат strcspn() и затем решить, был ли найден символ новой строки и, следовательно, следует ли читать до конца строки (или до конца файла).если нет EOL до EOF).

...