为什么我会得到这个奇怪的角色?

时间:2016-12-13 23:27:29

标签: c++

为什么我的C ++程序会在图片中创建下面显示的奇怪字符?左侧带有黑色背景的图片来自终端。带有白色背景的右侧图片来自输出文件。之前,它是一个“\ v”,现在它改为某种占星符号或符号来表示男性。 0_o这对我没有意义。我错过了什么?如何让我的程序输出只是一个反斜杠v?

enter image description here enter image description here

请参阅下面的代码:

// SplitActivitiesFoo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

int main()
{
    string s = "foo:bar-this-is-more_text@\venus  \"some more text here to read.\"";
    vector<string> first_part;
    fstream outfile;
    outfile.open("out.foobar");

    for (int i = 0; i < s.size(); ++i){

        cout << "s[" << i << "]: " << s[i] << endl;
        outfile << s[i] << endl;
    }



    return 0;
}

另外,假设在这种情况下我不想修改我的字符串''。我希望能够解析字符串的每个字符并以某种方式处理奇怪的字符。这是因为在实际程序中,字符串将从文件中读入并解析然后发送到另一个函数。我想我可以想出一种以编程方式添加反斜杠的方法......

3 个答案:

答案 0 :(得分:4)

您使用的终端很可能无法破译垂直空间代码“\ v”,因此打印其他内容。在我的终端上打印:

foo:bar-this-is-more_text@
                          enus  "some more text here to read."

将“\ v”更改或代码打印到:

String s = "foo:bar-this-is-more_text@\\venus  \"some more text here to read.\"";

答案 1 :(得分:4)

  

如何让我的程序输出只是反斜杠v?

如果你想要反斜杠,那么你需要转义它:"@\\venus"

这是必需的,因为反斜杠表示下一个字符应该被解释为特殊的东西(注意,当你想要双引号时,你已经在使用它了)。所以除非你说出来,否则编译器无法知道你真的想要反斜杠。

因此,字面反斜杠字符的语法为\\。字符串文字("\\")和字符文字('\\')都是这种情况。

  

为什么我的C ++程序会在图片中创建下面显示的奇怪字符?

您的字符串包含\v控制字符(垂直制表符),其显示方式取决于您的终端和字体。看起来您的终端正在使用传统MSDOS代码页中的符号。

我为你找到了一张图片here,它正好显示了值为11(0x0b)的垂直制表符(vt)条目的符号:

ASCII table

  

另外,假设在这种情况下我不想修改我的字符串''。我希望能够解析字符串的每个字符并以某种方式解决这个奇怪的角色。

好吧,我刚刚看到你将上述部分添加到你的问题中。现在你处境艰难。因为您的字符串文字实际上包含字符v或任何反斜杠。它只在代码中出现。如前所述,编译器已经解释了这些字符并替换它们。

如果您坚持打印v而不是垂直制表符出于某些与XY问题无关的疯狂原因,那么您可以为每个字符构建一个查找表,然后用其他字符替换不需要的字符:

char lookup[256];
std::iota( lookup, lookup + 256, 0 );  // Using iota from <numeric>
lookup['\v'] = 'v';

for (int i = 0; i < s.size(); ++i)
{
    cout << "s[" << i << "]: " << lookup[s[i]] << endl;
    outfile << lookup[s[i]] << endl;
}

现在,这不会打印反斜杠。要撤消字符串,请查看std::iscntrl。它依赖于语言环境,但您可以使用它。或者只是一些天真的东西:

const char *lookup[256] = { 0 };
s['\f'] = "\\f";
s['\n'] = "\\n";
s['\r'] = "\\r";
s['\t'] = "\\t";
s['\v'] = "\\v";
s['\"'] = "\\\"";
// Maybe add other controls such as 0x0E => "\\x0e" ...

for (int i = 0; i < s.size(); ++i)
{
    const char * x = lookup[s[i]];
    if( x ) {
        cout << "s[" << i << "]: " << x << endl;
        outfile << x << endl;
    } else {
        cout << "s[" << i << "]: " << s[i] << endl;
        outfile << s[i] << endl;
    }
}

请注意,无法正确重建最初出现在代码中的转义字符串,因为有多种方法可以转义字符。包括普通人物。

答案 2 :(得分:0)

  

我错过了什么?如何让我的程序输出只是反斜杠v?

你正在逃避字母v。要打印反斜杠和v,请逃避反斜杠。 也就是说,打印双反斜杠和v。

\\v