#c
#c
Вопрос:
Я пытаюсь создать программу, которая будет выделять память для чтения нового символа до тех пор, пока не будет прочитан символ null, но, похоже, это не работает
Printf в строке, которая прокомментирована (после условия цикла while), показывает мне, на какое значение указывает c i, я только что проверил, и даже если он показывает мне символ NULL (он просто печатает ‘- —‘, я предполагаю, что это символ NULL?), цикл продолжается.
char *read(char *c) {
int i=0;
c=(char*)malloc(1);
scanf("%c", c i);
while (*(c i)) {
//printf("-- %c --", *(c i));
i ;
c=(char*)realloc(c,i 1);
scanf("%c", c i);
}
return c;
}
Комментарии:
1. Что вы подразумеваете под нулевым символом ?
2. » Я предполагаю, что это символ NULL? «. Почему вы предполагаете и угадываете вслепую? Вы можете просто распечатать порядковое значение символа, используя спецификатор формата %d вместо %c. Тогда вы увидите , какой символ у вас там есть, независимо от того, доступен ли сам символ для печати или нет…
3. Почему вы игнорируете возвращаемое значение
scanf()
? Как вы можете определить, когда произошла ошибка или была предпринята попытка чтения после окончания ввода, если вы этого не делаете?4. Кроме того,
getchar()
и друзья — лучший выбор, если вы читаете символ за раз.scanf()
для этого слишком много.5. Еще один момент, о котором больше никто не упоминает. malloc() без free в той же функции не является хорошим шаблоном, поэтому делайте это только тогда, когда это необходимо. Это приводит к утечкам памяти. Существуют лучшие шаблоны для достижения такого же поведения, однако за счет циклов. Например, вызывающий вызывает функцию, чтобы узнать, сколько выделить. Вызывающий выделяет буфер и выполняет обратный вызов с выделенным буфером. Тогда существует ЧЕТКИЙ КОНТРАКТ о том, кто будет освобождать память.
Ответ №1:
Ваша реализация не останавливается, потому что она никогда не считывает NULL
символ. Когда вы нажимаете клавишу типа RETURN / ENTER, консоль генерирует последовательность перевода строки (которая является « n
» в некоторых операционных системах, таких как Linux, или « rn
» в некоторых других, таких как Windows).
С учетом сказанного, вы могли бы затем изменить свое while
условие, чтобы проверить, является ли прочитанный символ 'n'
или 'r'
завершить чтение, вместо того, чтобы проверять, был ли он NULL
. Однако это решение остановило бы чтение, как только пользователь нажмет клавишу возврата.
Комментарии:
1. Вау, это сработало, о, мой глобус, большое спасибо, эта штука доставила мне головную боль. Я предположил, что нулевой символ добавляется автоматически при нажатии enter, но если он сгенерировал только новую строку, вы знаете, как добавить нулевой символ в конце строки? Или вы не можете сделать это в консоли?
2. Это определенно можно сделать: вам просто нужно
realloc()
снова добавить один новый символ в вашу строку и присвоить этому символу значениеNULL
, делая это сразу после вашегоwhile (...) {...}
цикла.3. Я имел в виду, можете ли вы добавить нулевой символ из консоли после того, как вы ввели то, что хотели прочитать, но если новая строка генерируется автоматически, я думаю, это было бы довольно бессмысленно, поскольку вы можете просто добавить его после завершения цикла while, как вы сказали.
4. Насколько я понимаю,
NULL
никогда не генерируется при операции чтения с использованиемscanf()
спецификатора со%c
для чтения со стандартного устройства ввода («клавиатуры»). Это потому, что%c
спецификатор считывает символ иNULL
работает не как символ, а как своего рода «заполнитель» для представления «нет символа». Резюме:%c
никогда не преобразует ни один пользовательский ввод (с клавиатуры) в null.5. Для длинного ответа о том, что считается новой строкой, en.wikipedia.org/wiki/Newline . Кроме того, нужно уметь корректно обрабатывать EOF перед новой строкой.