Как изменить длину getline по умолчанию

Я пытаюсь решить проблему, и в процессе я ввожу строки с помощью getline следующим образом (часть моей основной функции)

 size_t n1=0,n2=0;
  char *a=0, *b=0;   
 getline(&a,&n1,stdin);
 getline(&b,&n2,stdin);

но независимо от того, какой ввод я даю, значение n1 и n2 всегда сохраняется как 120 . Как я могу решить эту проблему, чтобы сохранить точный размер строки, которую я ввожу

От документацияIf *lineptr is not null, the behavior is undefined if *lineptr is not a pointer that can be passed to free or if *n is less than the size of the allocated memory pointed to by *lineptr. lineptr в вашем случае будет a или b. Вам нужно их инициализировать, иначе у вас будет неопределенное поведение.

G.M. 17.03.2022 17:12

чтение документация — хорошее начало.

OldProgrammer 17.03.2022 17:14

@G.M. спасибо, что указали, что я действительно пропустил запись здесь, но в моем исходном коде *lineptr инициализируется значением null, но все же размер n1 и n2 равен 120

user 17.03.2022 17:15

В: Если вам нужен "точный размер строки, которую я ввожу"... тогда почему бы просто не прочитать возвращаемое значение getline()???

paulsm4 17.03.2022 17:20

@ paulsm4, насколько меня учили, n1 должен хранить точное количество строк, которые я даю в качестве входных данных, но независимо от того, какую строку я даю, я получаю те же 120, что и размер строк

user 17.03.2022 17:22

Вы не можете изменить значение по умолчанию, которое выделяет getline(). Если вам нужен буфер точного размера, используйте strdup() на входе. Или заранее выделить меньший размер, и сказать getline() какой это: size_t n1 = 32; char *a0 = malloc(n1);. Но getline() выбирает разумное значение по умолчанию, которое обычно позволяет избежать перераспределения при чтении входных данных — длина большинства строк не превышает 120 (или 128, или 256, или любое другое значение по умолчанию, которое использует getline()).

Jonathan Leffler 17.03.2022 17:34

@JonathanLeffler спасибо, у меня есть сомнения, что я использовал эту нотацию несколько раз раньше, но у меня никогда не было такой ошибки, раньше она сохраняла точную длину строки, которую я ввел в качестве входных данных, но почему сейчас это не удается

user 17.03.2022 17:38

Это не ошибка; это ожидаемое поведение getline(). Возможно, вы использовали другую реализацию getline()? Возможно, вы читали строки, постоянно превышающие минимальный размер буфера. Вы должны создать MCVE, воспроизводящее старое поведение, и объяснить, чем отличается ваш текущий код. Спецификация для getline() гарантирует, что для хранения текущих данных достаточно места, что означает, что может быть выделено больше места, чем минимально необходимое. Это уменьшает количество перераспределений памяти.

Jonathan Leffler 17.03.2022 17:43

@JonathanLeffler Я думаю, что не могу прикрепить скриншот, но когда размер строки огромен, все равно его выделяемый размер составляет 120

user 17.03.2022 17:50

Скриншоты имеют ограниченную ценность. Если вам это нужно, найдите мой адрес электронной почты в моем профиле и отправьте мне информацию. Включите URL-адрес вопроса. И включите необходимую информацию в виде обычного текста, если это вообще возможно — скопируйте и вставьте вывод, а не снимок экрана. Включите код, конечно.

Jonathan Leffler 17.03.2022 19:17

В: «Насколько меня учили, n1 должен хранить точное количество строк, которые я даю в качестве входных данных». О: Как вы, надеюсь, теперь понимаете, это НЕПРАВИЛЬНО. «n» — это размер вашего буфера (или индикатор того, что система должна использовать функцию malloc() для буфера), НЕТ «размер строки». Вот для чего нужно возвращаемое значение.

paulsm4 17.03.2022 22:02
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
11
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

How can I overcome this problem to store the exact size of string I input

Во-первых, вы должны перестать относиться к этому как к проблеме и относиться к этому как к нормальному поведению getline. Вы должны адаптироваться к getline, а не ожидать, что он приспособится к вам.

getline выделяет разумное количество места для работы. Выделение меньшего объема пространства может потребовать getline более частого перераспределения пространства, поскольку постоянный ввод требует все больших и больших выделений. Это приведет к пустой трате ресурсов, включая энергию и время.

n1 или n2, переданные getline посредством второго параметра, устанавливаются на размер выделенного пространства, а не на длину прочитанного ввода, и вы не можете изменить это, если не считать изменения реализации getline. getline не помещает длину ввода в n1 или n2.

Чтобы получить длину прочитанного ввода, сохраните возвращаемое значение getline:

size_t l1 = getline(&a, &n1, stdin);
size_t l2 = getline(&b, &n2, stdin);

Если выделенное пространство вызывает серьезную озабоченность, используйте realloc, чтобы сообщить программе управления памятью, что избыточное пространство не требуется:

char *temp = realloc(a, n1 = l1+1);
if (!temp) a = temp;
temp = realloc(b, n2 = l2+1);
if (!temp) b = temp;

Некоторые реализации realloc, скорее всего, будут игнорировать попытки уменьшить выделенное пространство, особенно когда выделенный размер невелик.

использование возвращаемого значения строки get сработало, спасибо. Но у меня никогда не возникало таких ошибок, даже если я использую те же обозначения, почему сейчас?

user 17.03.2022 17:44

@user Вы можете назвать это ошибкой, но это не так. Если вы проверите неправильные переменные, вы можете получить неожиданные результаты. Ожидание конкретного результата для n1 не подтверждается спецификацией. Единственное, чего можно ожидать, это «достаточно большой». Любая реализация может решить вести себя по-другому, а также изменяться между версиями.

Gerhardh 17.03.2022 19:11

Другие вопросы по теме