std::getline() 不忽略白色 space

std::getline() does not ignore white space

我是 C++ 的新手,我在阻止 getline 读取文本文件末尾的换行符时遇到了一些问题。我尝试使用换行符截断它,然后使用“,”传递给定界符,但它不起作用。你能帮我理解发生了什么以及为什么我无法实现我想要做的事情吗?

我编辑了此 post 以更正 getline() 的错误,而不是可用的错误。但是我不知道如何传输此 getline() 字符串以防止使用 '\n' 字符

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
static int Ncol = 5;
int main()
{
    int ctr=0,Nrow;
    std::string line,line1;
    std::ifstream myFile1;

    Nrow = 4;
    std::cout.precision(15);
    std::fixed;

    double* input = new double[Nrow*Ncol];
    double* ftrue = new double[Nrow];

    myFile1.open("./Data_codelink_test/test.txt");
    
    while(ctr<Nrow)
    {   
        std::getline(myFile1,line1,','); // This gives me line1 with the new line character
        std::cout<<"Read "<<line1<<std::endl;
        input[ctr] = std::stold(line1);
        std::cout<<"Stored "<<input[ctr]<<std::endl;
        ctr++;  
    }
    myFile1.close();

我的test.txt看起来像这样

1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5

我想要一个大小为 20 的向量以这种方式存储值

1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5

我看到的唯一问题(更新:在编辑之前使用 原始 代码)是您调用 std::getline('\n') 的次数 (25) 多于您的实际行数在文件 (4) 中。到达 EOF 时,您不会终止循环。请改用此循环条件:

while ((ctr < (Nrow*Ncol)) && std::getline(myFile1, line))

Nrow*Ncol 项已存储在数组中或 std::getline() 无法读取文件中的下一行时,这将结束循环。

也就是说,考虑使用 std::vector 而不是 new[]。让vector随着每一行成功读取而动态增长,例如:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>

int main()
{
    std::ifstream myFile1("./Data_codelink_test/test.txt");

    std::vector<double> input;
    std::string str;

    std::cout << std::fixed << std::setprecision(15);

    while (std::getline(myFile1, str))
    {
        std::istringstream iss(str);
        std::getline(iss, str, ',');
        std::cout << "Read " << str << std::endl;
        input.push_back(std::stold(str));
        std::cout << "Stored " << input.back() << std::endl; 
    }
    myFile1.close();

    ...
}

更新:使用您提供的任何一个代码片段都无法获得您想要的结果。在原始代码中,您可以很好地阅读这些行,但随后您只能提取每行中的第一个数字。在您编辑的代码中,您读取的是逗号分隔的数字,完全不考虑行,因此您会定期读取一个中间有换行符的字符串。

std::getline() 一次只能处理 1 个分隔符。因此,要解析 std::getline() 所拥有的数据类型,您需要 2 个循环 - 一个循环读取每一行,一个循环拆分每一行,例如:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>

static int Ncol = 5;

int main()
{
    std::ifstream myFile1("./Data_codelink_test/test.txt");

    int ctr = 0, Nrow = 4, maxElems = Nrow*Ncol;
    std::string str;

    double* input = new double[maxElems];

    std::cout << std::fixed << std::setprecision(15);

    while ((ctr < maxElems) && std::getline(myFile1, str))
    {
        std::istringstream iss(str);
        while ((ctr < maxElems) && std::getline(iss, str, ',')) {
            std::cout << "Read " << str << std::endl;
            input[ctr] = std::stold(str);
            std::cout << "Stored " << input[ctr] << std::endl;
            ++ctr;
        }
    }
    myFile1.close();

    ...
}

或者,使用 std::vector:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>

int main()
{
    std::ifstream myFile1("./Data_codelink_test/test.txt");

    std::vector<double> input;
    std::string str;

    std::cout << std::fixed << std::setprecision(15);

    while (std::getline(myFile1, str))
    {
        std::istringstream iss(str);
        while (std::getline(iss, str, ',')) {
            std::cout << "Read " << str << std::endl;
            input.push_back(std::stold(str));
            std::cout << "Stored " << input.back() << std::endl;
        }
    }
    myFile1.close();

    ...
}

std::getline 只接受单个字符作为分隔符:

使用两个循环读取数据更清晰如下:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
static int Ncol = 5;
int main()
{
    int column=0,Nrow;
    std::string line,field;
    std::ifstream myFile1;

    Nrow = 5;
    std::cout.precision(15);
    std::fixed;

    double* input = new double[Nrow*Ncol];
    double* ftrue = new double[Nrow];

    myFile1.open("./Data_codelink_test/test.txt");

    int row = 0;
    while (std::getline(myFile1, line))
    {
        std::stringstream stream(line);
        int column = 0;
        while(column < Ncol)
        {   
            std::getline(stream,field,','); // This gives me line1 with the new line character
            std::cout<<"Read "<<field<<std::endl;
            input[row *  Ncol + column] = std::stold(field);
            std::cout<<"Stored "<<input[row *  Ncol + column]<<std::endl;
            column++;  
        }
        row++;
    }
    myFile1.close();
}

结果是: