尝试在C++中制作 ASCII 表,无法使"special characters"正确显示



我正在做一项作业,我需要以表格格式打印出 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+i 的偏移量。 由于这是一个相当随机的地址,你会得到垃圾。请改用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's 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这四个额外的 lette 可以节省您以后的调试时间。

最新更新