2011-01-27 2 views
2

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

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

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

ответ

6

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

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

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

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

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

printf("%c", buff[strlen(buff)-1]); 
+0

Спасибо. Как получить доступ к символам? Если бафф равен 1024 и e.g пользователь вводит строку из 10 символов, если я хочу получить доступ к последнему символу, мне нужно выполнить итерацию по массиву, чтобы найти escape-символ? Что, если я использовал указатель? например char * word; а затем установите слово на вход из scanf. Как я могу получить доступ к персонажам? – jarryd

+0

Будет обновлен ответ. –

+0

Хорошо спасибо. Я не знаю, почему у меня есть идея, что все должно быть написано на языке C. :) – jarryd

1

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

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

2

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

#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 с некоторым поддерживающим кодом, чтобы выяснить, если линия ввода слишком долго.

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

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

Использование 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 

(что второй один вступал CTRLD, немедленный конец файла).

Смежные вопросы