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

Я хочу читать данные от пользователя, используя программу C. Я не хочу использовать массив вроде,

char names[50]; 

потому что если пользователь дает строку длиной 10, то оставшиеся пространства теряются.

Если я использую указатель на символ,

 char *names; 

то мне нужно выделить память для этого таким образом,

 names = (char *)malloc(20 * sizeof(char)); 

В этом случае также существует возможность потери памяти.

Итак, мне нужно динамически выделять память для строки, которая точно такая же, как длина строки.

Предположим,

Если пользовательский ввод "stackoverflow" , тогда выделенная память должна быть 14 (т. Е. Длина строки = 13 и 1 дополнительное пространство для «\ 0»).

Как я мог это достичь?

Прочитайте по одному символу за раз (используя getc(stdin) ) и произведите строку ( realloc ), когда вы идете.

Вот функция, которую я написал некоторое время назад. Обратите внимание, что он предназначен только для ввода текста.

 char *getln() { char *line = NULL, *tmp = NULL; size_t size = 0, index = 0; int ch = EOF; while (ch) { ch = getc(stdin); /* Check if we need to stop. */ if (ch == EOF || ch == '\n') ch = 0; /* Check if we need to expand. */ if (size <= index) { size += CHUNK; tmp = realloc(line, size); if (!tmp) { free(line); line = NULL; break; } line = tmp; } /* Actually store the thing. */ line[index++] = ch; } return line; } 

У вас может быть массив, который начинается с 10 элементов. Прочитать входной символ по символу. Если это произойдет, перераспределите еще 5. Не самое лучшее, но потом вы можете освободить другое пространство позже.

Если вы должны избавить память, читайте char по char и realloc каждый раз. Производительность умрет, но вы пощадите это 10 байт.

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

Вы также можете использовать регулярное выражение, например следующий fragment кода:

 char *names scanf("%m[^\n]", &names) 

получит всю строку от stdin, динамически распределяя объем пространства, который он занимает. После этого, конечно, вы должны иметь свободные names .

Ниже приведен код для создания динамической строки:

 void main() { char *str, c; int i = 0, j = 1; str = (char*)malloc(sizeof(char)); printf("Enter String : "); while (c != '\n') { // read the input from keyboard standard input c = getc(stdin); // re-allocate (resize) memory for character read to be stored str = (char*)realloc(str, j * sizeof(char)); // store read character by making pointer point to c str[i] = c; i++; j++; } str[i] = '\0'; // at the end append null character to mark end of string printf("\nThe entered string is : %s", str); free(str); // important step the pointer declared must be made free } 
 char* load_string() { char* string = (char*) malloc(sizeof(char)); *string = '\0'; int key; int sizer = 2; char sup[2] = {'\0'}; while( (key = getc(stdin)) != '\n') { string = realloc(string,sizer * sizeof(char)); sup[0] = (char) key; strcat(string,sup); sizer++ } return string; } int main() { char* str; str = load_string(); return 0; } 

Это более простой подход

 char *in_str; in_str=(char *)malloc(512000 * sizeof(char)); enter code herescanf("\n%[^\n]",in_str); 

Вот fragment, который я написал, который выполняет ту же функциональность.

Этот код похож на тот, который написал Кунал Вадхва .

 char *dynamicCharString() { char *str, c; int i; str = (char*)malloc(1*sizeof(char)); while(c = getc(stdin),c!='\n') { str[i] = c; i++; realloc(str,i*sizeof(char)); } str[i] = '\0'; return str; } 

Сначала определите новую функцию для чтения ввода (в соответствии со структурой вашего ввода) и сохраните строку, а это означает, что используется память в стеке. Установите длину строки, достаточную для ввода.

Во-вторых, используйте strlen для измерения точной используемой длины строки, сохраненной ранее, и malloc для выделения памяти в куче, длина которой определяется strlen . Код показан ниже.

 int strLength = strlen(strInStack); if (strLength == 0) { printf("\"strInStack\" is empty.\n"); } else { char *strInHeap = (char *)malloc((strLength+1) * sizeof(char)); strcpy(strInHeap, strInStack); } return strInHeap; 

Наконец, скопируйте значение strInStack в strInHeap с помощью strcpy и верните указатель на strInHeap . strInStack будет освобожден автоматически, поскольку он только выйдет из этой strInStack .

  • Размер строки кешей L1 и L2
  • Как инициализировать память новым оператором в C ++?
  • Объясните эту реализацию malloc из книги K & R
  • Чтение больших файлов в Java
  • Методы classа, которые создают новые экземпляры
  • Можно ли удалить не новый объект?
  • Размещение массива-new требует неопределенных накладных расходов в буфере?
  • Эффективные C ++ строки (интернирование, веревки, копирование на запись и т. Д.)
  • Что же случилось с использованием GC.Collect ()?
  • std :: вектор и непрерывная память многомерных массивов
  • Как работают realloc и memcpy?
  • Давайте будем гением компьютера.