Как проверить длину входной строки в C

У меня есть эта функция, которая проверяет, является ли строка такой:

void get_string(char *prompt, char *input, int length)
{
    printf("%s", prompt);                                   
    fgets(input, length, stdin);
    if (input[strlen(input) - 1] != '\n')
    {
        int dropped = 0;
        while (fgetc(stdin) != '\n')
        {
            dropped++;
        }
        if (dropped > 0)
        {
            printf("Errore: Inserisci correttamente la stringa.\n");
            get_string(prompt, input, length);
        }
    }else{
        input[strlen(input) - 1] = '\0';
    }
    return;
}

С помощью этой функции я могу повторить ввод, только если строка длиннее length.

Как мне это сделать, если я должен также проверить, короче ли строка?

@AjayBrahmakshatriya Это обрезает строку, удаляя (возможную) новую строку в конце.

Some programmer dude 28.05.2018 11:52

@Someprogrammerdude мой плохой, упустил из виду условие. Спасибо.

Ajay Brahmakshatriya 28.05.2018 11:56

Вам также необходимо изменить свою функцию type, чтобы обеспечить значимый возврат, указывающий на успех / неудачу. char *get_string(...) будет хорошим выбором, позволяющим вернуть NULL в случае ошибки или действительный указатель в противном случае. Вам необходимо проверить возвращатьсяfgets - на этом этапе можно сгенерировать ручной EOF.

David C. Rankin 28.05.2018 11:56
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
2 061
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Если строка короче, об этом позаботится fgets. Буфер не будет заполнен, новая строка будет помещена в конец строки.

Просто проверьте, идет ли strlen(input) < length после fgets. Если это условие оценивается как истинное, вы читаете меньше, чем максимальное количество байтов, возможное благодаря размеру буфера.

Код OP подвержен хакерской атаке и может вызвать неопределенное поведение.

// What happens if the first character read is a null character?
fgets(input, length, stdin);
if (input[strlen(input) - 1] != '\n')

Когда fgets() считывает ввод, Входнулевой символ не является особенным. Он читается и сохраняется, как и любой другой персонаж.

Если это патологический случай, input[0] == 0 и strlen(input) - 1 - это SIZE_MAX. input[SIZE_MAX], безусловно, является доступом за пределы массива, поэтому неопределенное поведение.


Чтобы проверить, не прочитал ли fgets() всю строку, последний буферный символ должен быть ненулевым, а затем проверить, становится ли он равным 0.

assert(input && length > 1);

input[length - 1] = '\n';

// check `fgets()` return value
if (fgets(input, length, stdin) == NULL) {
  return NULL;
}

if (input[length - 1] == '\0' && input[length - 2] != '\n') {
  // more data to read.

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