Обработка ввода строки в C - PullRequest
2 голосов
/ 27 января 2011

Если массив символов необходимо объявить до того, как он будет использован, как его объявить, чтобы его можно было использовать для хранения ввода?

Например, пользователь вводит предложение или серию слов.Как это хранится, чтобы им можно было манипулировать?

Какой правильный способ, чем просто объявить массив, достаточно большой для обработки ожидаемого ввода?

Ответы [ 3 ]

6 голосов
/ 27 января 2011

Если вы говорите о консольном входе , у вас нет другого выбора, кроме как иметь буфер FIXED SIZE и использовать функцию secure , не позволяющую хранить более FIXED_SIZE ваш буфер.

Примером может быть:

char buff[1024];
fgets(buff, 1024, stdin); // to read from standard input

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

Если вы хотите получить доступ к последнему символу, введенному пользователем:

printf("%c", buff[strlen(buff)-1]);
2 голосов
/ 27 января 2011

Я обычно использую следующую функцию:

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

#define OK       0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
    int ch, extra;

    // Get line with buffer overrun protection.
    if (prmpt != NULL) {
        printf ("%s", prmpt);
        fflush (stdout);
    }
    if (fgets (buff, sz, stdin) == NULL)
        return NO_INPUT;

    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.
    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? TOO_LONG : OK;
    }

    // Otherwise remove newline and give string back to caller.
    buff[strlen(buff)-1] = '\0';
    return OK;
}

Используется безопасный от переполнения буфера fgets с некоторым вспомогательным кодом для определения, была ли введенная вами строка слишком длинной.

Конечно, вы можете читать частичные строки и выполнять перераспределение памяти для хранения входной строки произвольного размера, но обычно более чем достаточно просто установить достаточно большую верхнюю границу и учесть это (например, 1 КБ).Если кто-то вводит больше, чем это для своего имени или адреса, они, вероятно, просто глупы: -)

Я на самом деле использовал этот трюк (частичное чтение и reallocs), чтобы вводить пользователя раньше, но, чтобы бытьЧестно говоря, необходимость в этом была настолько редкой, что она не попала в мой репозиторий "важных фрагментов исходного кода".

Использование fgets предотвращает возможность переполнения буфера, которое является большой опасность для пользовательского ввода.


Если вы хотите проверить этот код, попробуйте добавить:

int main (void) {
    int rc;
    char buff[10];

    rc = getLine ("Enter string> ", buff, sizeof(buff));
    if (rc == NO_INPUT) {
        printf ("No input\n");
        return 1;
    }

    if (rc == TOO_LONG) {
        printf ("Input too long\n");
        return 1;
    }

    printf ("OK [%s]\n", buff);

    return 0;
}

и некоторые примеры запусков:

pax> ./qq
Enter string> hi bob
OK [hi bob]

pax> ./qq
Enter string>
No input

pax> ./qq
Enter string> hi ho the merry oh
Input too long

(этот второй вводил CTRL D , непосредственный конец файла).

1 голос
/ 27 января 2011

Ввод через буфер?(Пользователь записывает свой текст в буфер некоторого размера, когда буфер заполнен, программа изменяет размер целевого массива с помощью realloc)

(вам нужно использовать char * вместо char [])

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...