【问题标题】:Reading in UTF-8 Files读取 UTF-8 文件
【发布时间】:2011-07-08 15:48:45
【问题描述】:

我用的是VS 2008,需要读取带有UTF-8中文字符的文本文件。该文件是这样组织的:每行包含一个文档,并且文档是制表符分隔的(索引“选项卡”文档标题“选项卡”文档正文)。所以我需要做的是分隔选项卡上的行,然后用空格分隔第三列(文档正文)并将每个单词存储在一个向量中。当文件是 ANSI 编码时,所有这些都可以正常工作。但是当它是 UTF-8 时,它会抛出断言失败(无符号)(c+1)

我查看了不同的方法(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));
}

}

提前致谢

戴夫

【问题讨论】:

  • 上一个问题可能对stackoverflow.com/questions/4018384/…有帮助
  • 断言发生在代码的哪一行?
  • 它发生在这里: split(original_document," ",document);我还可以添加拆分方法。
  • 是的,我猜 Split 方法可能会调用 strtok() 之类的东西,这可能会在 UTF-8 序列上出错

标签: c++ visual-studio-2008 file-io utf-8


【解决方案1】:

您需要先将 UTF-8 文件转换为 UTF-16 (wstring),然后才能进行任何解析。

当您使用 Windows 时,您可以使用 MultiByteToWideChar 来完成此操作

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

里面有一些源代码的链接。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
  • 2012-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多