С++ отображает char, а строки цикла

Я очень новичок в программировании, поэтому прошу прощения, если этот вопрос покажется абсурдно простым. Я работаю над некоторыми дополнительными вопросами в текущей главе моей книги по C++. На самом деле я нашел правильный ответ на проблему, но при этом столкнулся с ситуацией, которая сводит меня с ума, потому что я не могу понять, ПОЧЕМУ одно конкретное решение работает, а другое нет.

Итак, задача требует вывода значений ASCII от 32 до 127 в несколько строк по 16 символов в строке. Решение, к которому я пришел (которое работает правильно), таково:

#include <iostream>
using namespace std;

int main()
{
  char letter;
  int count = 0;

  for (letter = 32; letter < 127; letter++, count++)
    {
      if (count == 16)
        {
          cout << endl;
          count = 0;
        }
      cout << letter << " ";
    }

  cout << endl;

  return 0;

}

Опять же, приведенный выше код работает нормально и делает то, что я хочу. Сложность заключается в том, что я пробовал до этого. Я попытался решить ту же проблему с вложенным циклом while, например:

#include <iostream>
using namespace std;

int main()
{
  char letter = 32;
  int count;

  while (letter < 127)
    {
      count = 0;
      while (count < 16)
        {
          cout << letter << " ";
          letter++;
          count++;
        }
      cout << endl;
    }

  cout << endl;

  return 0;

}

Этот цикл while просто работает бесконечно, а также выдает какой-то мусор после нужных мне символов ASCII, и я не могу понять, почему. Что еще более странно, так это то, что если я изменяю переменную 'letter' в коде с помощью циклов while на int вместо char, он работает именно так, как я хочу, и завершается, когда должен, просто отображая фактические числа вместо ASCII. ценности.

Только когда «буква» является символом, я получаю бесконечный цикл. Я уверен, что это что-то действительно простое, и я, возможно, просто слишком устал, чтобы видеть это прямо сейчас, но любая помощь/подсказки будут высоко оценены! Хотя технически я получил ответ, меня сводит с ума то, что я не знаю, ПОЧЕМУ второй ответ так ужасно терпит неудачу.

Заранее спасибо.


person nik    schedule 31.01.2012    source источник


Ответы (3)


Ответ прост, достаточно правдив. Вот что происходит - (signed)char может иметь значения в диапазоне [-128, 127] во внутреннем цикле после того, как вы выведете строку до 112, вы увеличите count еще на 16, и поэтому вы также увеличите букву на 16, это делает букву равной 112 + 16 = 128, что из-за диапазона подписанных символов фактически переполняется и становится -128. Таким образом, после этого выполнения внутреннего цикла условие внешнего цикла все еще выполняется: -128 ‹ 127. Вот почему вы также получаете странные символы - это будут значения от -128 до 32.

Как решить проблему? Изменить проверку во внутреннем цикле: while (count < 16 && letter < 127)

person Ivaylo Strandjev    schedule 31.01.2012
comment
Ах, это имеет смысл. Благодарю вас! - person nik; 31.01.2012

Внутренний цикл while завершается, когда буква == 48, 64,..., 128. Но поскольку это (со знаком) char, 128 интерпретируется как -128, и внешний цикл не завершится. Измените внутренний цикл на

while (count < 16 && letter < 127)

чтобы получить то же поведение, что и в вашем первом примере.

Или измените букву на int, если можно печатать все символы, включая 127:

int letter = 32;
...
cout << (char)letter << " ";
person Henrik    schedule 31.01.2012

Попробуйте этот код:

#include <iostream>
using namespace std;

int main()
{
  int letter;
  for (letter = 32; letter < 128; ++letter)
  {
     if (letter != 32 && letter % 16 == 0)
         cout << endl;

     cout << (char)letter << ' ';
  }
}
person NMI    schedule 31.01.2012