2011-09-22 96 views
0

我必須先用西里爾語讀取一個文件,然後隨機選取一行隨機數並將修改後的文本寫入不同的文件。拉丁字母沒有問題,但我遇到了西里爾語文本的問題,因爲我收到了一些垃圾。所以這就是我試圖做的事情。用西里爾文在C++中讀寫文件

說,文件input.txt

ааааааа 
ббббббб 
ввввввв 

我要讀它,並把每行插入載體:

vector<wstring> inputVector; 
wstring inputString, result; 
wifstream inputStream; 
inputStream.open("input.txt"); 
while(!inputStream.eof()) 
{ 
    getline(inputStream, inputString);    
    inputVector.push_back(inputString); 
} 
inputStream.close();  

srand(time(NULL)); 
int numLines = rand() % inputVector.size(); 
for(int i = 0; i < numLines; i++) 
{ 
    int randomLine = rand() % inputVector.size(); 
    result += inputVector[randomLine]; 
} 

wofstream resultStream; 
resultStream.open("result.txt"); 
resultStream << result; 
resultStream.close(); 

所以,我怎麼能與西里爾工作,所以它產生可讀的東西,不只是符號?

+0

你是什麼意思'可讀的東西,不只是符號?'什麼'result.txt'看起來像什麼,你看起來像什麼? –

+0

我想得到像ааааааавввввввsmith,但獲得2A = 04?@>(水手那樣)。我不知道如何閱讀西里爾文,以及如何寫西里爾文。 –

+0

文件的編碼是什麼? – AraK

回答

1

因爲你看到的東西像■AAAAAAA 1♦1♦1♦1♦1♦1♦1♦2♦ 2♦2♦2♦2♦2♦2♦打印到控制檯,看起來input.txt以UTF-16編碼編碼,可能是UTF-16 LE + BOM。如果將文件的編碼更改爲UTF-8,則可以使用原始代碼。

之所以使用UTF-8是,不管char類型文件流中的,basic_fstream的底層basic_filebuf使用codecvt對象char對象/流來自焦炭的對象流轉換類型;即在讀取時,從文件中讀取的數據流將被轉換爲wchar_t數據流,但在寫入時,wchar_t數據流將轉換爲char數據流,然後寫入該文件。在std::wifstream的情況下,codecvt對象是標準std::codecvt<wchar_t, char, mbstate_t>的實例,它通常將UTF-8轉換爲UCS-16。

作爲上the MSDN documentation page for basic_filebuf解釋:類型basic_filebuf與char類型的內部緩衝器*創建不管由類型參數ELEM指定的char_type

對象。這意味着在將Unicode字符串(包含wchar_t字符)寫入內部緩衝區之前,它將轉換爲ANSI字符串(包含字符字符)。

類似的,讀取Unicode字符串時(含有wchar_t字符),則basic_filebuf轉換從文件中讀取到wchar_t串的ANSI字符串返回到getline和其他的讀操作。

如果將input.txt的編碼更改爲UTF-8,則原始程序應該正常工作。

以供參考,這對我的作品:

#include <cstdlib> 
#include <ctime> 
#include <fstream> 
#include <iostream> 
#include <string> 
#include <vector> 

int main() 
{ 
    using namespace std; 

    vector<wstring> inputVector; 
    wstring inputString, result; 
    wifstream inputStream; 
    inputStream.open("input.txt"); 
    while(!inputStream.eof()) 
    { 
     getline(inputStream, inputString); 
     inputVector.push_back(inputString); 
    } 
    inputStream.close(); 

    srand(time(NULL)); 
    int numLines = rand() % inputVector.size(); 
    for(int i = 0; i < numLines; i++) 
    { 
     int randomLine = rand() % inputVector.size(); 
     result += inputVector[randomLine]; 
    } 

    wofstream resultStream; 
    resultStream.open("result.txt"); 
    resultStream << result; 
    resultStream.close(); 

    return EXIT_SUCCESS; 
} 

注意的result.txt編碼也將是UTF-8(通常情況下)。

+0

現在就像一個魅力工程!感謝您的幫助和MSDN鏈接! –

1

爲什麼你會使用wifstream - 你確信你的文件包含(依賴於系統的)寬字符序列?幾乎可以肯定情況並非如此。 (最主要的原因是系統的寬字符集在C++程序的範圍之外並不確定)。

相反,剛讀輸入字節流,因爲它是和回聲它相應:

std::ifstream infile(thefile); 
std::string line; 
std::vector<std::string> input; 

while (std::getline(infile, line)) // like this!! 
{ 
    input.push_back(line); 
} 

// etc. 
+0

試圖以這種方式讀取文件,然後輸出到控制檯如下所示: ■aaaaaaa 1♦1♦1♦1♦1♦1♦1♦ 2♦2♦2♦2♦2♦2♦2 ♦ –

+0

確保您的環境設置爲與文件編碼對應的正確語言環境,並且您的終端支持所需的字符集。 –