2011-07-08 9 views
3

私はVS 2008を使用しており、UTF-8中国語の文字を含むテキストファイルを読む必要があります。ファイルは次のように編成されています。各行には文書が含まれ、文書はタブ区切りです(索引 'タブ'文書タイトル 'タブ'文書本体)。だから私は、タブ上の行を区切ってから3番目の列(doc本体)をスペースで区切り、各単語をベクトルに格納する必要があります。ファイルがANSIでエンコードされている場合、これはすべて正常に動作します。しかし、それがUTF-8のときにスローされ、アサーションエラー(符号なし)(c + 1)< = 256になります。現在の機能とフローを維持し、可能な限り第三者のライブラリとして使用したいと思います。UTF-8ファイルで読む

私はさまざまな方法(ustream、wstreamなど)を見てきましたが、実際にそれらを使用する方法について少し混乱しています。ここで

は、ファイルを読み込み方法である:

bool TabDelimitedSource::setup_next_buff_reader() {   
this->current_source_file += 1; 
bool no_more_files = false; // assume we have no more files by default 

/** If there are still files int the directory load the next file*/ 
if(current_source_file < (data_source_files.size())){    
    string file_path = (this->data_source_files[this->current_source_file]); 
    string full_path = data_source_dir + file_path ; 
    buff_reader->open((char*)full_path.c_str()); 
} 
else{ 
    no_more_files = true; 
} 

    return no_more_files; // let the caller know whether there was another file or not 
} 

そして、これは構文解析を行い方法であって、

vector<string> TabDelimitedSource::getNext() { 
// Returns the next document (a given cell) from the file(s) 
string row; // Return NULL if no more documents/rows 
vector<string> document; 

try{ 
    //Read each line in the file, corresponding to and individual document 
    std::getline(*buff_reader,row,'\n'); 
} 
catch (ifstream::failure e){ 
    ; // Ignore and fall through 
} 

if (row.size()>0){ 
    this->current_row += 1; 
    vector<string> cells; 
    this->split(row, "\t", cells); // Split the row on tabs 
    try{  
     string original_document = cells[column_holding_doc]; 
     try{ 
      split(original_document," ",document); 
     }catch (std::out_of_range e){ 
      throw std::out_of_range ("Out of Range"); // ignore and fall through 
     } 
    } 
    catch (std::out_of_range e){ 
     throw std::out_of_range ("Out of Range"); 
    } 
} 
else{ 
    // We're at the end of the current file, try loading the next one 
    buff_reader->close(); 
    bool no_more_files = this->setup_next_buff_reader(); 
    // If there was another file to load, recurse to get its first document 
    if (!no_more_files){      
     return this->getNext(); 
    } 

} 

// Return our arrayList as an array... there has to be a better way to do this 
vector<string> return_val ; 
if(document.size()>0){ // return NULL by default 
    for(int i=0; i<(int)document.size(); i++){ 
     return_val.push_back(document[i]);   
    } 
} 

return return_val; 
} 

スプリット方法:中

void TabDelimitedSource::split(const string& str, const string& delim, vector<string>& result){ 
size_t start_pos = 0; 
size_t match_pos; 
size_t substr_length; 

while((match_pos = str.find(delim, start_pos)) != string::npos){ 
    substr_length = match_pos - start_pos; 
    if (substr_length > 0){ 
     result.push_back(str.substr(start_pos, substr_length)); 
    } 
    start_pos = match_pos + delim.length(); 
} 

substr_length = str.length() - start_pos; 

if (substr_length > 0){ 
    result.push_back(str.substr(start_pos, substr_length)); 
} 

} 

感謝前払い

Dave

+0

この前の質問は役に立ちましたか?http://stackoverflow.com/questions/4018384/stl-and-utf-8-file-input-output-how-to-do-it – Connman

+0

アサーションを行うコードの行起こる? – PeskyGnat

+0

ここで起こります:split(original_document、 ""、document);分割メソッドを追加することもできます。 – David

答えて

2

解析する前に、UTF-8ファイルをUTF-16(wstring)に変換する必要があります。

Windowsを使用しているとして、あなたはこの

http://msdn.microsoft.com/en-us/library/dd319072(v=VS.85).aspx

を達成するためにMultiByteToWideCharのを使用することができます内のソースコードへのリンクがあります。

+0

これをしないでください。 [あなたはユニコードが何であるかわからない](http://stackoverflow.com/questions/1049947/should-utf-16-be-considered-harmful)。 – ybungalobill

+0

まだ物流を進めていますが、これはうまくいくようです。 - ありがとう! – David