2017-01-16 2 views
1

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

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

char* dyninp (char str[], int *n) { 
    char ch; 
    int i = 0; 
    do { 
    ch = getchar(); 
    str = (char *) realloc(str, (i+1)*sizeof(char)); 
    str[i] = ch; 
    i++; 
    } while (ch != '\n'); 

    /*substitute '\n' with '\0'*/ 
    str[i-1] = '\0'; 

    if (n != NULL) { 
    /*i contains the total lenght, including '\0'*/ 
    *n = i-1; 
    } 

    /*because realloc changes array's address*/ 
    return str; 
} 

/*it is called in this way: 
char *a; 
int n; 
a = dyninp (a, &n); 
*/ 

Этот код работает, но у меня есть несколько вопросов о нем:

  1. Почему это работает?
    Я не понимаю, почему, когда я его выполню, я также могу удалить символы перед нажатием enter. Функция getchar() читает только один символ на каждой итерации, который записывается в массив, так как я могу удалить некоторые из них?
    Если getchar() удаляет предыдущий символ при получении '\ 127', тогда цикл должен продолжаться, как и любой другой символ. Но этого не происходит, потому что, когда цикл заканчивается, «i» всегда содержит точное количество элементов.

  2. Является ли мой код эффективным? Если это не так, как я могу сделать это лучше (даже используя встроенные функции)?

ответ

1
  1. Если вы не поставили терминал в «сырой» режим, операционная система не вводит доступ к приложению, пока вы не нажмете return. Редактирование ввода обрабатывается операционной системой. Когда вы вызываете getchar(), он считывает символ из этого входного буфера, а не непосредственно из терминала.

  2. Существует функция POSIX getline(), которая делает то же самое.

1

Ответ на первый вопрос:

Причина этого, вероятно, буферизация в терминале водителя. В разделе примечаний приводится краткое описание: here. Функция getchar() не получает никакого ввода до тех пор, пока строка не будет выполнена пользователем в терминале, когда она получит всю строку и вернет символ символом. Поэтому удаление является особенностью вашего терминала, а не вашей программы.

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