2016-12-13 63 views
2

为什么我的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:[email protected]\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; 
} 

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

+5

'\ v'是一个垂直制表,反斜线反斜线 –

+0

它创建的图像中所示的奇怪的字符。我认为这是转义字符的一些问题,但我不知道如何解决这个问题,并简单地获取字符之前解析字符之前的文本。 – user3870315

+0

不妨做一个正式的答案,@JosephYoung。我不认为OP完全了解发生了什么事情,我想不出有什么理由来解决这个问题。 – user4581301

回答

3

我怎么能有我的节目输出只是一个反斜杠V'

如果你想有一个反斜杠,那么你需要逃生它:"@\\venus"

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

字面反斜杠字符因此具有语法\\。在字符串文字("\\")和字符文字('\\')中都是这种情况。

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

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

我发现了一个像你here,它显示了垂直制表(VT)项的值11(0x0B中)正是符号:

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; 
    } 
} 

要知道有没有办法正确地再现转义字符串,因为它最初出现在代码中,因为有多种方式来转义字符。包括普通字符。

+0

良好的形象,你可以指出其011我花了一段时间来找到它。 – dreamcrash

+0

感谢您的回答。我明天会研究这个。 :)你可以尝试编码查找功能?我已经在Python中完成了这些,但不是C++。所以我不完全确定如何使用查找表。 – user3870315

+0

你是什么意思?我几乎只是为你查找代码。但目前还不清楚你为什么要这样做。你的问题有一个根本的误解,会导致你做错了。 – paddy

4

最有可能的终端,你正在使用不能破译垂直空间代码“\ v”,从而打印别的东西。在我的终端它打印:

foo:[email protected] 
          enus "some more text here to read." 

要打印“\ V”型变化或代码:

String s = "foo:[email protected]\\venus \"some more text here to read.\""; 
+0

为什么是-1?如果我不正确,请随时指出错误。所以我可以删除答案或更正答案。 – dreamcrash

+0

我不想手动添加转义字符,但是因为当我在我的程序中使用此字符串时,我从其他位置获取该字符串。我不知道这是否有意义,但我宁愿不改变字符串,只是找出解析它的方式,而不接收奇怪的字符。我的例子只是一个简单的测试程序,看看我是否可以用C++解析字符串。 – user3870315

+0

如果你只是想解析字符串,你不会有问题,“字符”将是相同的,只有你的终端打印方式可能会有所不同。 – dreamcrash

0

我错过了什么?我怎样才能让我的程序输出只是一个反斜杠v?

您正在转义字母v。要打印反斜杠和v,请转义反斜杠。 即,打印双反斜线和诉

\\v 
+1

@ user3870315您可以在这里查看C++中的转义序列列表:http://en.cppreference.com/w/cpp/language/escape – user3437460

+0

我不是哥们,如果您不相信只是删除您的问题你会看到我的代表不会改变。 – dreamcrash

+0

@dreamcrash不,我相信你。谁投下了这个,关心放弃一个理由? – user3437460

相关问题