Я работаю над назначением, где мне нужно распечатать таблицу ASCII в формате таблицы, как показано на рисунке ниже.
http://i.gyazo.com/f1a8625aad1d55585df20f4dba920830.png В настоящее время я не могу получить специальные слова/символы для отображения (8, 9, 10, 13, 27, 32, 127).
Здесь он работает: http://i.gyazo.com/80c8ad48ef2993e93ef9b8feb30e53af.png
Вот мой текущий код:
#include <iomanip>
#include <iostream>
using namespace std;
int main()
{
cout<<"ASCII TABLE:"<<endl;
cout<<endl;
for (int i = 0; i < 128; i++)
{
if (i <= 32)
cout << "|" << setw(2)
<<i
<< setw(3)
<< "^" << char (64+i) <<"|";
if (i >= 33)
cout << "|" << setw(3)
<<i
<< setw(3)
<<char (i) << "|";
if((i+1)%8 == 0) cout << endl;
}
return 0;
}
8 Back Space
9 Horizontal Tab
10 New Line
13 carriage return
27 Escape (Esc)
32 Space
127 Del
Поскольку над этими символами ASCII не отображается видимый или напечатанный символ. Вот почему вы, возможно, думаете, что не получаете эти ценности.
Я не знаю, какова ваша реальная проблема, но вы еще не получили ответа о том, как печатать специальные коды.
Запустив вашу программу, я вижу, что у вас есть некоторые незначительные проблемы с выравниванием. Если в этой проблеме отметим, что setw(3)
применяется только к следующему элементу:
cout << setw(3) << "^" << char (64+i); // prints " ^A" instead of " ^A".
Если вы попытаетесь
cout << setw(3) << "^"+ char (64+i); // ouch !!!!
вы получите неопределенное поведение (мусор), потому что "^" является указателем на строку, а добавление char(64+i)
понимается как добавление смещения 64 + я к этому указателю. Поскольку это довольно случайный адрес, вы получите мусор. Вместо этого используйте std::string
.
Другая разница, которую я вижу между выходом вашей программы и ожидаемым результатом, заключается в том, что вы не печатаете код специальных символов. Если эта проблема, либо используйте оператор switch
(очень повторяющийся здесь), либо много if/else
или используйте ассоциативную map
.
Здесь альтернативное предложение, объединяющее все это:
map<char, string>special{ { 8, "BS " }, { 9, "\\t " }, { 10, "\\n " }, { 13, "CR " }, { 27, "ESC" }, { 32, "SP " }, { 127, "DEL" } };
cout << "ASCII TABLE:" << endl << endl;
for (int i = 0; i < 128; i++) {
cout << "|" << setw(3)<<i<<setw(4); // setw() only applies to next
if (iscntrl(i) || isspace(i)) { // if its a control char or a space
auto it = special.find(i); // look if there a special translation
if (it != special.end()) // if yes, use it
cout << it->second;
else cout << string("^") + char(64 + i)+ string(" "); // if not, ^x, using strings
}
else if (isprint(i)) // Sorry I'm paranoïd: but I always imagine that there could be a non printable ctrl ;-)
cout << char(i)+string(" ") ; // print normal char
cout << "|";
if ((i + 1) % 8 == 0) cout << endl;
}
Теперь несколько дополнительных советов:
iscntrl()
, isspace()
, isprint()
. До тех пор, пока вы используете только ascii, вы можете делать так, как вы. Но поскольку вы переходите к интернационализации и широким символам, это становится все более громоздким для этого, тогда как существуют простые широкие эквиваленты, такие как iswcntrl()
, iswspace()
, iswprint()
.if
: Если вы знаете, что только один из них должен применяться, приложите усилия, чтобы написать if... else if
эти четыре дополнительных lettes могут сэкономить вам часы отладки позже.
if((i+1)%8 == 0) cout<< endl;
Удалить все,if
условия7,15,23.....