2016-12-13 104 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