C: Считать буквы до тех пор, пока не будет вставлена ​​конкретная запись

Я немного заржавел в C. Я выполняю школьное задание, в котором меня просят создать программу, которая получает пользовательский ввод, после чего печатает вывод. Если количество символов превышает 50, ничего не распечатывать и не запрашивать их повторно. Выход не должен печатать счет (в данном случае 4).

Это то, что у меня есть до сих пор:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main ()
{ /*Start of main*/

printf("Type any word you'd like <= 50 characters.\nType quit to exit:\n");

char word[50];
int wordLength = 0;

    while (strcmp(word, "quit") != 0)
    {/*open of while loop (strcmp ... != 0)*/

    scanf("%s\n", word);
    wordLength = strlen(word);
    if (wordLength > 50)
        {
            printf("Try again, >= 50 characters!:\n");
            scanf("%s", word);
            wordLength = strlen(word);
        }
    printf("%d\n", wordLength);

    }/*End of while loop (strcmp... != 0)*/

return 0;
}/*End of main*/

Кажется, я не могу получить длину сразу после отправленного слова. Кажется, он становится шатким. Он показывает номер ПОСЛЕДНЕГО отправленного слова после ввода нового слова. Неважно, куда я положил printf, на это нужно время.

Может ли кто-нибудь объяснить мне, почему он такой медленный, и предложить метод, который я мог бы реализовать, чтобы ускорить его? Это школьное задание, пожалуйста, не давайте прямых ответов, но подскажите, как мне следует думать? :)

Я почти думаю, что это неэффективное кодирование с задержкой.

Вы все спасатели!!!


person HowbeitGirl    schedule 27.01.2015    source источник
comment
C-faq 12.17   -  person    schedule 27.01.2015
comment
массив 'char word[50]' необходимо инициализировать, так как первое, что делает код, это сравнивает первые 4 байта. предложить: 'char word[50] = {'\0'}. однако, чтобы разрешить ввод 50 байтов, char word[50] должен быть char word[51]', чтобы оставить место для байта завершения строки'   -  person user3629249    schedule 28.01.2015
comment
длина слова никогда не может быть равна › 50, если только массив word[] не был переполнен, что было бы неопределенным поведением и может/приведет к событию сбоя сегмента.   -  person user3629249    schedule 28.01.2015
comment
с символьным словом[51]... if(strlen(word) ›=50) { вывод сообщения о переполнении; memset(слово, '\0', sizeof(слово)); continue} чтобы устранить второй scanf и другие проблемы   -  person user3629249    schedule 28.01.2015
comment
эта строка: ''эта строка: 'scanf(%s\n, word);' 1) не имеет ограничений по размеру, поэтому он может переполнить входной буфер. предложить: 'scanf(%50s[\n], word)' 2) необходимо проверить возвращаемое значение из scanf(), чтобы убедиться, что операция прошла успешно.   -  person user3629249    schedule 28.01.2015


Ответы (2)


Удалить \n из первого scanf()

scanf("%s\n", word);
#---------^

Благодаря @remyable, \n имеет другое значение в scanf() — не то, которое вы ожидаете здесь читать с новой строки. См. C-faq 12.17

Кроме того, проверка ввода более 50 символов неверна. Вы бы попали в переполнение буфера. Ищите другой способ ограничить это.

person Rohan    schedule 27.01.2015
comment
Поведение scanf при встрече с пробелом (т. е. новой строкой) выглядит следующим образом: директива, состоящая из пробельных символов, выполняется путем считывания ввода до первого непробельного символа (который остается непрочитанным), или до тех пор, пока символы не будут прочитаны. Директива никогда не подводит. (§7.21.6.2/5) - person ; 27.01.2015
comment
Спасибо Рохан и ремябель! :) Я ценю объяснения относительно \n! - person HowbeitGirl; 28.01.2015

Код имеет несколько проблем

  • оператор while использует word до инициализации word
  • scanf не ограничивает количество символов, записываемых в word
  • strlen может вернуть число >50 только в том случае, если вы переполнили буфер
  • код запрашивает только один раз, он должен повторяться до тех пор, пока пользователь не поймет это правильно
person user3386109    schedule 27.01.2015