Как динамически распределять пространство памяти для строки и получать эту строку от пользователя?
Я хочу читать данные от пользователя, используя программу C. Я не хочу использовать массив вроде,
char names[50];
потому что если пользователь дает строку длиной 10, то оставшиеся пространства теряются.
Если я использую указатель на символ,
- Как я могу получить размер массива из указателя в C?
- Ядро обнуляет память?
- Переменная, по-видимому, изменяет размер на каждой итерации цикла - что?
- Мусорный коллектор MATLAB?
- Как работает механизм сбора мусора?
char *names;
то мне нужно выделить память для этого таким образом,
names = (char *)malloc(20 * sizeof(char));
В этом случае также существует возможность потери памяти.
Итак, мне нужно динамически выделять память для строки, которая точно такая же, как длина строки.
Предположим,
Если пользовательский ввод "stackoverflow"
, тогда выделенная память должна быть 14
(т. Е. Длина строки = 13 и 1 дополнительное пространство для «\ 0»).
Как я мог это достичь?
- Временная сложность распределения памяти
- Проверьте, указывает ли указатель на выделенную память в куче
- Почему моя программа работает медленнее, если вы перебираете ровно 8192 элементов?
- Можно ли программно определить размер массива C ++? А если нет, то почему?
- максимальная память, которую malloc может выделять
- Удаляет ли вызов деструктор?
- Почему / когда использовать `intptr_t` для литья типов в C?
- Как узнать, указывает ли указатель на кучу или стек?
Прочитайте по одному символу за раз (используя 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
.