由于隐藏/控制字符,在C ++中读取文本文件的行失败

突触

我有两个文本文件,它们在文本编辑器中看起来是相同的,但是用于读取文件的C ++代码为每个文件产生不同的行数。我无法弄清楚文件的不同之处,或者如何在我的C ++代码中适应这种差异。

让我解释...

我有两个文本文件d1.txt和d2.txt。每个包含100个数字,每行1个。当我在vim中打开两个文件并输入时:set list!,只有100行,每行包含一个数字和每行最后一个数字之后的行尾字符($)。换句话说,在vim中查看它们时,它们看起来相同,只是数字的精度不同。精度有所不同,因为一个文件来自MATLAB,另一个文件来自Gnumeric。

快速比较文件会呈现以下输出(为了节省空间,我使用大括号“ [...]”省略了部分):

1,28c1,28
< 0.01218465532007
       [...]
< 0.01327976337895
---
> 0.0121846553200678
       [...]
> 0.0132797633789485
30,100c30,100
< 0.01329705254301
       [...]
< 0.00017832496354
---
> 0.0132970525430057
       [...]
> 0.000178324963543758
\ No newline at end of file

尽管有消息说第二个文件(d2.txt)的末尾没有换行符,但是如上所述,在vim中检查文件的最后几行时,我看不到任何区别。

我创建了一个C ++函数readVectorFromFile(std::vector<double>&,const string),该函数返回从相应文本文件读取的行数。当我使用代码读取文本文件时:

std::cout << "d1.txt has " << readVectorFromFile(v1,"./d1.txt") << " lines.\n";
std::cout << "d2.txt has " << readVectorFromFile(v1,"./d1.txt") << " lines.\n";

我得到的输出:

d1.txt has 99 lines.
d2.txt has 100 lines.

该函数以以下方式定义:

int readVectorFromFile(vector<double>& vec, const string& fullFilePathName) {

    int value, numLines;
    char line[10000];
    ifstream inFile;

    /* attempt to open file */
    inFile.open(fullFilePathName.c_str());
    if (inFile.fail()) {
        LOG(FATAL) << "Unable to open file \"" << fullFilePathName.c_str() << "\" for reading.";
    } else {
        cout << "Importing vector from file " << fullFilePathName.c_str() << "\n";
    }

    /* records the number of lines in the input file */
    numLines = static_cast<int>( count(istreambuf_iterator<char>(inFile),
                                       istreambuf_iterator<char>(), '\n') );

    /* start file over from beginning */
    inFile.clear();
    inFile.seekg(0, ios::beg);

    vec.clear(); // clear current vec contents
    vec.reserve(numLines);

    /* read value from each line of file into vector */
    for(int i=0; i<numLines; ++i) {
        inFile.getline(line, 10000);
        vec.push_back( strtod(line,NULL) );
    }

    inFile.close(); // close filestream

    return numLines; // return the number of lines (values) read

}

在vim中查看它们时,为什么看不到这些文件之间的区别?导致此问题的上述功能有根本上的错误吗?

迪特玛·库尔(DietmarKühl)

根据您的描述,两个文件之一的末尾没有换行符。您可以使用od -c file | less来查看文件,例如,查看文件的确切内容,包括其字符代码。

也就是说,您读取线的方法可能会得到改进:只需读取一条线,检查是否可以读取并进行处理。这样,就无需预先计算行尾的数量:

for (std::string line; std::getline(inFile, line); ) {
    vec.push_back(strtod(line.c_str()));
}

就个人而言,我可能只会首先阅读数字,例如:

for (double value; inFile >> value; ) {
    vec.push_back(value);
}

好吧,这并不是将doubles序列读入向量的真正方法,但这是:

std::vector<double> vec((std::istream_iterator<double>(inFile)),
                        std::istream_iterator<double>());

(代替多余的括号,您可以在C ++ 11中使用统一的初始化符号)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章