Количество слов в C

У меня есть программа подсчета слов на языке C, которая исключает специальные символы и цифры:

int main(){
    char str[100];
    int i, j = 0;
    int len;
    char choice;
    
    do {
        printf("Enter String: ");
        fgets(str, sizeof(str), stdin);

        len = strlen(str);

        for (i = 0; i < len; i++) {
            if ((str[i] >= 'A' && str[i] <= 'Z') || 
              (str[i] >= 'a' && str[i] <= 'z')) //checks if its upper or lowercase {
                if (str[i] != ' ' && (str[i + 1] == ' ' || str[i + 1] == '\0'))//checks if the current character is a space and also the end of the string{
                    j++;
                }
            }
        }

        printf("Word count: %d\n", j);

        printf ("Try again?(Y/N): ");
        scanf (" %c", &choice);    
     
        getchar ();//use to clear input buffer
    } while (choice == 'y' || choice == 'Y');

    return 0;  
}

Но он не учитывает первую строку после пробела и, кажется, становится немного запутанным, когда я продолжаю цикл.

Я пробовал менять значения массива, цикла, а также пытался спросить ИИ, что я пропустил, но предложения не сработали.

выход:

Enter String: i
Word count: 0
Try again? (Y/N): Y
Enter String: i have 3 Apples
Word count: 2
Try again? (Y/N): Y
Enter String: hello WORLD
Word count: 3
Try again? (Y/N): hello world

Несколько несвязанных комментариев: Смешивать fgets, scanf и getchar — плохая идея. Также используйте стандартные функции isalpha() и isspace() вместо проверок.

Eugene Sh. 14.03.2024 18:36
str[i] != ' ' всегда верно, туда не попасть, если иероглиф не буква. Я бы предложил просмотреть код в отладчике, чтобы увидеть, где что-то идет не так.
Retired Ninja 14.03.2024 18:37

Добро пожаловать в Stack Overflow! Пожалуйста, публикуйте код, данные и результаты в виде текста, а не скриншотов (как форматировать код в сообщениях ). Почему мне не следует загружать изображения кода/данных/ошибок? idownvotedbecau.se/imageofcode

Barmar 14.03.2024 18:41

@Roshina De Иисуса Вы не сбрасываете переменную j в цикле do- while.

Vlad from Moscow 14.03.2024 18:47

«первая строка после пробела не учитывается». Работайте с конечным автоматом — вы либо анализируете слово, либо анализируете пробел. Начните с состояния «пробел» и отсчитывайте в начале каждого слова, то есть когда состояние меняется с «пробела» на «слово».

Weather Vane 14.03.2024 18:49

У вас также есть isalpha(), isspace() и т. д., которые можно использовать. Кроме того: переименуйте переменную j в wordcount.

Weather Vane 14.03.2024 18:52

//...{ в нескольких местах делает { частью комментария; он не влияет на поток управления (и, конечно, не будет компилироваться).

Neil 14.03.2024 21:44
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
93
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для начала функция fgets может добавить символ новой строки '\n' к введенной строке.

Вы должны либо удалить его, например, как

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

или учтите в своих утверждениях if.

В противном случае в результате вы получите, например,

Enter String: i
Word count: 0

хотя по вашему описанию количество слов должно быть равно 1.

Во-вторых, вы не обнуляете переменную j внутри цикла do- while.

Это выражение

str[i] != ' '

во внутреннем операторе if всегда оценивается как логическая истина. Поэтому его присутствие в операторе if является излишним.

Также будет гораздо лучше использовать стандартную функцию isalpha вместо сравнения символов с символами. Также символ табуляции '\t', а также некоторые символы, не являющиеся буквами, могут разделять слова, как написано в вашем описании задачи, но вы это проигнорировали. Согласно вашему подходу, эта строка "one,two,three" содержит одно слово.

«гораздо лучше использовать стандартную функцию isalpa» --> да, но тогда isalpha() нужно получить значения unsigned char, а не char, которые могут быть отрицательными.

chux - Reinstate Monica 14.03.2024 22:57

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