Перейти к содержимому

Как считать строку неизвестной длины в си

  • автор:

C++ как считать из файла строку неизвестной длины?

есть txt файл, в ней есть строка, её длину не знаем, какой функцией воспользоваться чтобы считать её в программе в массив который размером будет с её длину? т. е нужен аналог strlen который сможет прочтитать строку в файле, либо какой-то другой костыль. Знаю что можно объявить массив символов длиной в 1000 и заливать туда строки да и все, но очень нужен именно такой костыль, чтобы считать кол-во элементов строки в файле, потом выделить память под массив в который она поместится и собственно туда её сохранить. Если что не так сказал поправьте.

Лучший ответ

roma shsЗнаток (390) 7 лет назад

тоже самое провернуть с текстовым файлом

Superior Oracle Мудрец (12356) Вместо std::cin используете std::ifstream.

Остальные ответы

roma shsЗнаток (390) 7 лет назад

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

int main()std::ifstream f(«filename.txt»);
std::string s;
getline(f, s);
// что-то дальше
return 0;
>

roma shsЗнаток (390) 7 лет назад

Denwer LollipopМастер (1963) 7 лет назад

К сожалению в mail.ru не умеют программировать. Я заинклудил string и fstream.

Как считать строку неизвестной длины в си

Для того, чтобы с помощь scanf() ввести строку, необходимо выделить для этого память. А если неизвестно, какова длина строки, то невозможно выделить правильное количество памяти. Как решать такую проблему?

char* str; scanf("%s", str);

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

char* str; str = new char [n]; scanf("%s", str);

где n — количество символов. Но! Если это самое количество неизвестно? P.S. Если тема уже обсуждалась то не тыкайте в поиск, я искал — не нашел. Заранее спасибо.

Помогли тебе — помоги другому.
Delphi Warrior
Регистрация: 15.08.2008
Сообщений: 2,502
Вам обязательно Сишный ввод? Или С++ тоже можно?

Mess with the best, die like the rest. (с) Hackers
Лабораторные, курсовые на Delphi\Pascal\C++
ya.flex-freelance@yandex.ru Icq — 636-954-303

Hacker19_90
Посмотреть профиль
Найти ещё сообщения от Hacker19_90

Лжец и смутьян
Форумчанин
Регистрация: 03.04.2009
Сообщений: 194
Помогли тебе — помоги другому.
C++,DirectX/OpenGL
Форумчанин
Регистрация: 09.01.2011
Сообщений: 422
Сообщение от Alt

Для того, чтобы с помощь scanf() ввести строку, необходимо выделить для этого память. А если неизвестно, какова длина строки, то невозможно выделить правильное количество памяти. Как решать такую проблему?

Использовать контейнеры переменной длины и по символу из потока копировать:

#include #include using namespace std; string str; while (1) < str+= cin.get(); if ( str.find("\n") != -1) //пока не будет переход строки break; >

Как выделить память для строки неизвестной длины?

Нужно считать из stdin строку (заканчивается \n),длина которой неизвестна.
Т.е. может быть
agdadsgasdfasdf
Или
asjdfhkasljdfhasd.
Я попытался сделать что-то такое, но получается, что, когда я получаю новый символ, массив chars переопределяется.

#include #include int main() < char *chars; int c,n=0; while((c=getchar()) != '\n')< chars = (char*)malloc(++n * sizeof(char)); chars[n-1] = c; >printf("%s\n", chars); >
  • Вопрос задан более трёх лет назад
  • 1814 просмотров

Комментировать

Решения вопроса 0

Ответы на вопрос 2

«I’m here to consult you» © Dogbert

Как это усовершенствовать?

An optional ‘m’ character. This is used with string conversions (%s, %c, %[), and relieves the caller of the need to allocate a corresponding buffer to hold the input: instead, scanf() allocates a buffer of sufficient size, and assigns the address of this buffer to the corresponding pointer argument, which should be a pointer to a char * variable (this variable does not need to be initialized before the call). The caller should subsequently free(3) this buffer when it is no longer required.

#include int main()

Ответ написан более трёх лет назад

Комментировать

Нравится 2 Комментировать

Сергей Горностаев @sergey-gornostaev Куратор тега C

Седой и строгий

const unsigned int MAX_LENGTH = 1 * 1024 * 1024; // Не выделять больше мегабайта памяти const unsigned int CHUNK_SIZE = 1024; // Выделять блоками по килобайту int main() < unsigned int str_len = CHUNK_SIZE; char *str_ptr = malloc(CHUNK_SIZE); // Выделяем первый килобайтный блок if (str_ptr == NULL) err(EXIT_FAILURE, "Не удалось выделить память!\n"); int c; unsigned int i; for (i = 0, c = EOF; (c = getchar()) != '\n' && c != EOF; i++) < str_ptr[i] = c; if (i == MAX_LENGTH) < free(str_ptr); err(EXIT_FAILURE, "Слишком много входных данных!\n"); >if (i == str_len) < // Блок заполнен str_len = i + CHUNK_SIZE; str_ptr = realloc(str_ptr, str_len); // Расширяем блок на ещё один килобайт >> str_ptr[i] = '\0'; // Признак конца строки printf("%s\n", str_ptr); free(str_ptr); str_ptr = NULL; return EXIT_SUCCESS; >

Ответ написан более трёх лет назад

Комментировать

Нравится 1 Комментировать

Ваш ответ на вопрос

Войдите, чтобы написать ответ

android

  • Android
  • +3 ещё

Какие есть доки по сборке APK/AAB с использованием Android NDK?

  • 1 подписчик
  • 30 дек. 2023
  • 65 просмотров

Ввод строки неизвестной длины через функцию

Мне дали задачу реализовать ввод строк неизвестной длины с консоли. Я решил ее написать через функцию getch() , с помощью которой записываю введенные символы в массив до определенного стоп-символа (в данном случае enter). Для удобства решил весь код ввода занести в функцию и столкнулся с проблемой, что введенные данные после вызова функции очищаются. Как можно решить проблему, желательно не прибегая к использованию глобальных переменных?

#include void readString(char *string); int main() < char *string = NULL; readString(string); for (int t = 0; t < 10; t++) printf("%c", string[t]); // Для проверки вывожу первые 10 символов free(string); getch(); return 0; >void readString(char *string) < char symbol; int counter = 0; while(1) < symbol = getch(); if (symbol == 13) break; printf("%c", symbol); counter++; string = (char*)realloc(string, counter * sizeof(char)); string[counter - 1] = symbol; >string[counter] = '\0'; printf("\n"); > 

Отслеживать
51.6k 201 201 золотой знак 63 63 серебряных знака 245 245 бронзовых знаков
задан 1 мая 2018 в 22:03
15 1 1 серебряный знак 3 3 бронзовых знака

что введенные данные после вызова функции очищаются Вообще-то программа должна была крашнуться. Параметром функции нужно сделать указатель на указатель void readString(char** string);

2 мая 2018 в 0:01
2 мая 2018 в 0:02
и хорошо бы из функции возвращать длину строки
2 мая 2018 в 0:03

и getch() что это за функция? в стандартном С нет такой функции. Есть getchar и getc. В Visual Studio есть _getch.

2 мая 2018 в 0:09

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

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

void readString(char *string) 

вы передаете в функцию значение указателя string . Когда вы меняете его — вы никак не меняете саму переданную переменную string .

Варианты — или передавайте в функцию адрес этой переменной

void readString(char **string) . readString(&string); 

и внутри функции работайте с *string — т.е. переменной, на которую указывает аргумент, или возвращайте новое значение из функции и присваивайте его:

char* readString(char *string) < . return string; >. string = readString(string); 

Способа получения строки с помощью getch() я в ответе не касаюсь.

Отслеживать
2,905 1 1 золотой знак 13 13 серебряных знаков 29 29 бронзовых знаков
ответ дан 2 мая 2018 в 2:52
219k 15 15 золотых знаков 119 119 серебряных знаков 230 230 бронзовых знаков

Самая первая Ваша ошибка это:

стоп-символа (в данном случае enter)

Не существует такого символа, как enter. Enter — кнопочка на клавиатуре. А символ есть перехода на новую строку, а именно ‘\n’

Что касается функции записи строки, то можно реализовать, например, так:

void readString (char ** s, size_t * len) < size_t delta = 10; char * str = (char *) malloc (delta * sizeof (char)); size_t size = delta; if (str == NULL) < throw "bad_alloc"; >char * buf; size_t n = 0; int c; while (1) < c = fgetc (stdin); if (c == EOF || c == ' ' || c == '\t' || c == '\n') < break; >if (n == size) < buf = (char *) malloc ((size + delta) * sizeof (char)); if (buf == NULL) < throw "bad_alloc"; >memcpy (buf, str, size * sizeof (char)); free (str); str = buf; size += delta; > str[n++] = c; > if (n != size) < buf = (char *) malloc (n * sizeof (char)); if (buf == NULL) < throw "bad_alloc"; >memcpy (buf, str, n * sizeof (char)); free (str); str = buf; > *len = n; *s = str; return; > 

Эта функция считает строку, как массив символов, но не как строку (строка завершается символов ‘\0’ )

Если же необходимо реализовать, как обычную строку, то функцию можно сделать следующего вида: void readString (char ** s) и конец вышенаписанного кода заменить на следующий:

 if ((n + 1) != size) < buf = (char *) malloc ((n + 1) * sizeof (char)); if (buf == NULL) < throw "bad_alloc"; >memcpy (buf, str, n * sizeof (char)); free (str); str = buf; > str[n] = '\0'; *s = str; return; > 

Замечу, что то, какой символ считать символом разрыва определяется в этой строке: if (c == EOF || c == ‘ ‘ || c == ‘\t’ || c == ‘\n’) < break; >. В данном примере концом строки (получается, что в данном примере под строкой больше подразумевается именно слово) считается один из символов: ‘ ‘ , ‘\t’ , ‘\n’ , либо конец потока.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *