Для цикла через массив, вызывающий бесконечный цикл
У меня есть фрагмент кода, который должен сбрасывать массив символов при нажатии клавиши ввода, только код зацикливается бесконечно, и я не могу понять, почему.
Существует массив символов, который получает новый символ при каждом нажатии клавиши. Когда клавиша ввода обнаружена, выполняется следующий код для очистки массива символов символами '\0' перед генерацией новой строки на экране:
int main()
{
char i;
char c;
char buffer[80];
i = 0;
c = 0;
while (c = bgetchar())
{
if (c == 13)
{
for (i = i; i >= 0; i--)
{
buffer[i] = '\0';
}
}
else
{
buffer[i] = c;
i++;
}
}
}
I увеличивается в основном цикле каждый раз, когда нажимается символ (кроме ввода (ASCII 13)). Символ также добавляется в буфер []. Этот код здесь не показан, но я могу его воспроизвести. Излишне говорить, что даже если этот код неправильно увеличивал i, цикл должен завершиться, когда я достигну 0 (и я должен достичь 0 в какой-то момент с учетом декремента).
Таким образом, теоретически, при нажатии клавиши ввода, если в строке 5 символов (и нет обратных пробелов), элементы buffer[] 0-4 будут иметь символы, а i будет равно 5. Цикл в коде должен замените элементы 5 на 0 символами '\0'. По общему признанию, начинать с элемента 5 не нужно, но это не должно вызывать того поведения, которое я испытывал.
Такое поведение заключается в том, что цикл выполняется бесконечно. Прямо сейчас я смог проверить это, используя мою функцию putchar для печати символа каждый раз при запуске цикла. Теперь я полагаю, что мог бы написать другую функцию, которая позволила бы мне также распечатать значение i, и я, вероятно, получил бы ответ на свой вопрос. Кроме того, как бы то ни было, бесконечный цикл возникает, когда я превращаю этот цикл в эквивалентный цикл "while".
Я просто хотел убедиться, что здесь нет чего-то очевидного, что могло бы вызвать бесконечный цикл. Извините, если это глупый вопрос. Спасибо за любую помощь. Программа запускается как необработанный двоичный файл в 16-битном реальном режиме. Я компилирую от bcc до as86 до финального двоичного файла.
Изменить: после дополнительной отладки я подтвердил, что я перехожу в цикл с правильным положительным значением (на основе количества символов в массиве, например, i = 7, если 7 символов). Однако в цикле for i меняет значение от -1 до -2 до бесконечности. Поскольку это не имеет смысла на основе значения входа i (или на основе условия цикла), есть ли вероятность, что это какая-то проблема с памятью или регистром?
Окончательное редактирование: похоже, проблема заключалась в условии>=, из-за которого i стал отрицательным. По какой-то причине это вызвало бесконечный цикл, хотя условие в цикле for проверяет наличие отрицательного i. Спасибо за помощь.
1 ответ
По какой-то причине это вызвало бесконечный цикл, хотя условие в цикле for проверяет отрицательное значение i.
"условие в проверках цикла for" истинно, но условие проверяется не везде, где это необходимо.
По крайней мере, одна проблема: попытка buffer[-1] = c;
что является неопределенным поведением (UB), которое может включать бесконечный цикл.
Когда ввод после (c == 13)
не 13, код пытается использовать этот UB.
while (c = bgetchar()) {
if (c == 13) {
for (i = i; i >= 0; i--) {
buffer[i] = '\0';
}
// now i == -1;
} else {
// No protection here that `i` is on the 0..79 range
buffer[i] = c;
i++;
}
}
for (i = i; i >= 0; i--)
сомнительна как первая buffer[i] = '\0';
находится на том, что не было установлено в другом buffer[i] = c; i++;
часть.
Я подозреваю, что нужно OP
// for (i = i; i >= 0; i--) {
for (i = i; i > 0; ) {
// buffer[i] = '\0';
buffer[--i] = '\0';
}
char i;
необычно. Я бы ожидал фиксированного подписанного типа, а неchar
которые могут быть подписаны или неподписаны. Возможноunsigned char i
(после исправления выше) или идиоматический size_t i;
для индексации массива.