2009-11-19 72 views
0

我試圖找出,如果我有兩個字符串是相同的,爲了單元測試的目的。第一個是預定義的字符串,硬編碼到程序中。第二個是使用std :: getline()從文本文件中讀取ifstream,然後將其作爲子字符串。這兩個值都存儲爲C++字符串。C++ - 當輸出到文本文件與控制檯輸出不同時出現string.compare問題?

當我輸出都用COUT進行測試的字符串到控制檯的,他們都似乎是相同的:

ThisIsATestStringOutputtedToAFile ThisIsATestStringOutputtedToAFile

然而,string.compare回報,說明他們是不相等的。當輸出到文本文件時,兩個字符串如下所示:

ThisIsATStringStringOutputtedToFile T^@ h^@ i^@ s^@ I^@ s^@ A^@ T^@ e^@ s^@ t^@ S^@ t^@ r^@^@^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^我猜這是一種編碼問題,如果我用我的母語(很好的舊C#),我wouldn不會沒有太多問題。就像我用C/C++和Vi一樣,並且坦率地說,並不知道該從哪裏出發!我試着尋找可能轉化爲/從ANSI/unicode的,也消除了奇怪的字符,但我什至不知道他們是否真的存在或不..

在此先感謝您的任何建議。

編輯 道歉,這是我第一次在這裏發帖。下面的代碼是我要如何完成整個過程:

ifstream myInput; 
ofstream myOutput; 

myInput.open(fileLocation.c_str()); 
myOutput.open("test.txt"); 

TEST_ASSERT(myInput.is_open() == 1); 

string compare1 = "ThisIsATestStringOutputtedToAFile"; 
string fileBuffer; 

std::getline(myInput, fileBuffer); 
string compare2 = fileBuffer.substr(400,100); 

cout << compare1 + "\n"; 
cout << compare2 + "\n"; 
myOutput << compare1 + "\n"; 
myOutput << compare2 + "\n"; 
cin.get(); 

myInput.close(); 
myOutput.close(); 

TEST_ASSERT(compare1.compare(compare2) == 0); 
+0

看起來你的第二個字符串是2byte unicode? – falstro 2009-11-19 09:38:40

+1

你需要告訴我們字符串的確切類型,你如何輸出它們,以及如何比較它們 - 請在代碼中。 – sbi 2009-11-19 09:40:12

回答

0

事實證明,問題是,myInput的文件編碼爲UTF-16,而比較的字符串是UTF-8。將它們與我爲這個項目(Linux,C/C++代碼)所具有的操作系​​統限制進行轉換的方式是使用iconv()函數。爲了保持我使用的C++字符串的兼容性,我最終將字符串保存到一個新的文本文件中,然後通過system()命令運行iconv。

system("iconv -f UTF-16 -t UTF-8 subStr.txt -o convertedSubStr.txt"); 

將輸出的字符串讀回來,然後給了我需要的格式的字符串,以便比較正常工作。

備註 我知道這不是最有效的方法。我已經擁有了Windows環境和windows.h庫的豪華,事情會變得更容易。在這種情況下,代碼在一些很少使用的單元測試中,因此不需要高度優化,因此某些文本文件的創建,銷燬和I/O操作不是問題。

0

我下面的作品,並寫入下面粘貼到文件中的文本。請注意嵌入到字符串中的'\0'字符。

#include <iostream> 
#include <fstream> 
#include <sstream> 

int main() 
{ 
    std::istringstream myInput("ThisIsATestStringOutputtedToAFile\x0 12ou 9 21 3r8f8 reohb jfbhv jshdbv coerbgf vibdfjchbv jdfhbv jdfhbvg jhbdfejh vbfjdsb vjdfvb jfvfdhjs jfhbsd jkefhsv gjhvbdfsjh jdsfhb vjhdfbs vjhdsfg kbhjsadlj bckslASB VBAK VKLFB VLHBFDSL VHBDFSLHVGFDJSHBVG LFS1BDV LH1BJDFLV HBDSH VBLDFSHB VGLDFKHB KAPBLKFBSV LFHBV YBlkjb dflkvb sfvbsljbv sldb fvlfs1hbd vljkh1ykcvb skdfbv nkldsbf vsgdb lkjhbsgd lkdcfb vlkbsdc xlkvbxkclbklxcbv"); 
    std::ofstream myOutput("test.txt"); 
    //std::ostringstream myOutput; 

    std::string str1 = "ThisIsATestStringOutputtedToAFile"; 
    std::string fileBuffer; 

    std::getline(myInput, fileBuffer); 
    std::string str2 = fileBuffer.substr(10,100); 

    std::cout << str1 + "\n"; 
    std::cout << str2 + "\n"; 
    myOutput << str1 + "\n"; 
    myOutput << str2 + "\n"; 

    std::cout << str1.compare(str2) << '\n'; 

    //std::cout << myOutput.str() << '\n'; 
    return 0; 
} 

輸出:

 
ThisIsATestStringOutputtedToAFile 
ThisIsATestStringOutputtedToAFile 
1

你是如何創建的myInput的內容?我猜想這個文件是用兩字節編碼創建的。您可以使用十六進制轉儲來驗證此理論,或使用其他編輯器來創建此文件。

的simpliest方法是啓動cmd.exe和類型

echo "ThisIsATestStringOutputtedToAFile" > test.txt

UPDATE:

如果你不能改變myInput文件的編碼,你可以嘗試使用寬字符的程序。即使用wstring代替stringwifstream代替ifstreamwofstreamwcout

+0

myInput的內容是一個自定義文件擴展名XML文件,儘管用vi打開它們顯示它被識別爲二​​進制文件。逐行閱讀和打印文件到控制檯顯示它很好,所以我猜我需要將它從二進制流轉換爲ACSII類型的流? – Smallgods 2009-11-19 10:10:15

+0

將文件打印到控制檯時,ASCII碼低於32的字符將被視爲控制碼(例如TAB,CR,LF等)。字符^ @(ASCII 0x00)不做任何事情,它只是被跳過。 由於這些^ @字符,Vi會將該文件識別爲二進制文件。 – 2009-11-19 10:14:08

+0

myInput文件看起來像二進制格式。一些更多的搜索引發了這篇文章,這使我在我的路上很好。歡呼的幫助! http://stackoverflow.com/questions/181634/simplest-efficient-ways-to-read-binary-and-ascii-files-to-string-or-similar-in-v – Smallgods 2009-11-19 12:51:43