Home > Net >  std::getline() does not ignore white space
std::getline() does not ignore white space

Time:11-16

I am new to C and I have some trouble preventing getline to read the new line character at the end of my text file. I tried truncating it using a newline character and then passing to a delimiter with ',' but it just doesnt work. Can you please help me understand what is going on and why I am not able to achieve what i intended to do?

I have edited this post to correct the mistake of getline() more than what is available. However I dont know how to transfer this getline() string to prevent taking the'\n' character

#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();

My test.txt looks like this

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

I would like to have a vector of size 20 to have values stored in this manner

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

CodePudding user response:

std::getline only accepts a single character as delimiter:

The result

CodePudding user response:

The only problem I see (UPDATE: with the original code before your edit) is you are calling std::getline('\n') more times (25) than you have actual lines in the file (4). You are not terminating your loop when EOF is reached. Use this loop condition instead:

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

This will end the loop when EITHER Nrow*Ncol items have been stored in the array OR std::getline() fails to read the next line in the file.

That being said, consider using a std::vector instead of new[]. Let the vector grow dynamically with each line that is successfully read, eg:

#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();

    ...
}

UPDATE: the result you want can't be achieved using either code snippet you have presented. In the original code, you were reading the lines fine, but then you were extracting only the 1st number in each line. In your edited code, you are reading comma-separated numbers without any regard to lines at all, so periodically you will read in a string that has a line break in the middle of it.

std::getline() can only handle 1 delimiter at a time. So, to parse the kind of data you have with std::getline(), you need 2 loops - one loop to read each line, and one loop to split up each line, eg:

#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();

    ...
}

Alternatively, using 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();

    ...
}
  • Related