Оператор if используется внутри функции getline() в C

Это программа для печати самой длинной строки. Из книги K&R по языку программирования C.

Я сомневаюсь, что это необходимость кода.

    if (c == '\n'){
     s[i]=c;
     ++i;
    }

в функции getLine().

#include<stdio.h>
# define MAXLINE 1000  /*maximum length of the input line*/

int getLine(char s[],int line);
void copy(char from[],char to[]);

int main(){
    int curr_len; //current line length
    int max_len = 0;  // maximum line length so far

    char curr_line[MAXLINE];             // Current input line
    char longest_line[MAXLINE];     // maximum line saved so far

    while((curr_len = getLine(curr_line,MAXLINE))>0){
        if (curr_len>max_len){
            copy(curr_line,longest_line);  //save the longest line
            max_len = curr_len;
        }
    }
    if (max_len>0){
        printf("%s\n",longest_line);
    }
    return 0;

}

/* getline: read a line into s, return length*/
int getLine(char s[],int maxline){
    int c,i;
    for(i=0;i<maxline-1 && (c = getchar())!=EOF && c!='\n';++i){
        s[i]=c;
        if (c == '\n'){
            s[i]=c;
            ++i;
        }
    }
    s[i]='\0';
    return  i;
}

/* copy: copy 'from' into 'to'; assume to is big enough */
void copy(char from[],char to[]){
    int i=0;
    while((to[i] = from[i])!='\0'){
        ++i;
    }
}

Пожалуйста, объясните, почему оператор if используется внутри функции getLine().

похоже на ошибку

Bodo 22.06.2023 21:46

@SOHAN D P Кажется, вы неправильно скопировали функцию. Насколько я знаю, в исходной функции оператор if помещается вне цикла for. :)

Vlad from Moscow 22.06.2023 22:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

я сомневаюсь, что это необходимость кода.

Да, это бесполезный код.

Учитывая, c == '\n' никогда не бывает правдой.

    for(i=0;i<maxline-1 && (c = getchar())!=EOF && c!='\n';++i){
        s[i]=c;
        if (c == '\n'){

Код не точно скопирован из «из книги по языку программирования C от K&R». (стр. 29, 2-е издание)

Похоже на ошибку рефакторинга ОП из книги. ОП добавил {} неправильно.

// More like K & R
int getLine(char s[],int lim){
    int c, i;
    for(i=0; i<lim-1 && (c = getchar())!=EOF && c!='\n';++i) // no bracket here
        s[i]=c;
    // This if is not part of the loop.
    if (c == '\n'){
       s[i]=c; // Also save the '\n`.
       ++i;
    }
    s[i]='\0';
    return  i;
} 

Код K&R имеет смысл - даже у него есть другие проблемы, такие как lim <= 1, не лучшая обработка ошибок ввода, ...

@SOHANDP Да, правильно расшифрованный код обрабатывает '\n' с if (c == '\n'){ s[i]=c; ++i; }.

chux - Reinstate Monica 22.06.2023 22:04

теперь я понял, если (c == '\n') { s[i]=c; ++я; } находится вне цикла for.

SOHAN D P 22.06.2023 22:18

Спасибо за ответ.

SOHAN D P 22.06.2023 22:18

Теперь, если бы вы предлагали c = 0; приспособиться к случаю, когда lim равно 0 или 1, поэтому c не присваивается в условии цикла, поэтому вы ссылаетесь на неинициализированный c после цикла… И код, безусловно, выиграет, гарантируя, что lim является не ноль и не отрицательный. И еще один момент, который следует отметить, это то, что POSIX имеет функцию getline() с совершенно другой сигнатурой и набором семантики — это имя больше не подходит для использования в POSIX-подобных системах.

Jonathan Leffler 22.06.2023 22:48

@JonathanLeffler Да, c==0 помогает, когда lim == 1. Общий дизайн функций getline_like() составлен из угловых случаев, которые часто плохо обрабатываются.

chux - Reinstate Monica 22.06.2023 23:14
Ответ принят как подходящий

Если мы удалим этот код, цикл все равно будет правильно завершаться при встрече с символом новой строки из-за условия c != '\n' в проверке завершения цикла. Однако длина строки, хранящейся в curr_len, не будет включать символ новой строки.

Почему это проблематично? Последующее сравнение в функции main, if (curr_len > max_len), будет ошибочным. Если символ новой строки не включен в вычисление длины, самая длинная найденная строка может оказаться неверной.

Рассмотрим следующий сценарий:

Вход:

Line 1
Line 2
Line 3

Если мы исключим символ новой строки из расчета длины, длина каждой строки будет:

Line 1: 6 (_excluding newline_)
Line 2: 6 (_excluding newline_)
Line 3: 6 (_excluding newline_)

В этом случае программа сделает ошибочный вывод, что строка 1 является самой длинной строкой, поскольку она имеет ту же длину, что и строки 2 и строки 3. Однако на самом деле строка 3 является самой длинной строкой, поскольку в ней есть дополнительный символ новой строки.

Включая символ новой строки в расчет длины, программа гарантирует, что сравнение if (curr_len > max_len) точно идентифицирует самую длинную строку. Он считает символ новой строки частью длины строки, позволяя правильно определить строку 3 как самую длинную строку длиной 7 (_включая символ новой строки).

Следовательно, включение фрагмента кода if (c == '\n') { ... } необходимо для правильного учета символа новой строки и обеспечения точного сравнения при поиске самой длинной строки.

Надеюсь теперь понятно!

Вы говорите: «Однако строка 3 на самом деле самая длинная строка, поскольку в ней есть дополнительный символ новой строки». Я не понимаю? Строка 3 имеет ту же длину, что и две другие строки.

Jonathan Leffler 22.06.2023 22:35

Добро пожаловать в Stack Overflow! Большинство или все ваши ответы, вероятно, были полностью или частично написаны ИИ (например, ChatGPT), и возможная галлюцинация, упомянутая @JonathanLeffler, заставляет меня думать, что это тоже может быть. Имейте в виду, что публикация материалов, созданных искусственным интеллектом, здесь запрещена. Если вы использовали инструмент ИИ, чтобы помочь с каким-либо ответом, я бы посоветовал вам удалить его. Спасибо!

NotTheDr01ds 22.06.2023 23:11

Читатели должны тщательно и критически рассмотреть этот ответ, поскольку информация, сгенерированная ИИ, часто содержит фундаментальные ошибки и дезинформацию. Если вы наблюдаете проблемы с качеством и/или у вас есть основания полагать, что этот ответ был сгенерирован искусственным интеллектом, пожалуйста, оставьте соответствующий отзыв. Команда модераторов может использовать вашу помощь для выявления проблем с качеством. м

NotTheDr01ds 22.06.2023 23:11

Другие вопросы по теме