简体   繁体   中英

Read comma separated values with stray whitespaces from a textfile in c++

I have a file that contains string,int,int values in multiple lines.

Delhi,12,13
Mumbai,100 , 101
Kolkata,11,  12

The values are separated by commas but there can be stray whitespaces in between.My current code is this :

 #include<cstdio>
#include<iostream>
#include<string>

using namespace std;


int main()
{

    FILE *f = fopen("input.txt","r");
    int lines = 0;
    char c = getc(f);
    while(c != EOF)
    {
        if(c == '\n')
        {
            lines++;
        }
        c = getc(f);
    }
    lines++;

    string arr[lines];
    int t1[lines];
    int t2[lines];

    char s1[100],s2[100],s3[100];
    int x,y;
    fclose(f);
    f = fopen("input.txt","r");

    while (fscanf(f,"%99[^,],%99[^,],%99[^,]", s1, s1, s2)==3)
    {
        cout << s1 << s2 << s3 << endl;
    }
}

This doesn't seem to quite properly read the values and display on the screen first of all. How do I read the string and the integer values here(which may have stray whitespaces) and store them into an array (three arrays to be precise) ?

The problem is on this line:

while (fscanf(f,"%99[^,],%99[^,],%99[^,]", s1, s1, s2)==3)

It tries to scan up to the next comma character ',' , which occurs on the next line. Replace with %99[^\n] to fix this problem:

while (fscanf(f,"%99[^,],%99[^,],%99[^\n]", s1, s1, s2)==3)

Try doing this:

   fscanf(f,"%[^, ]%*[ ,]%d%*[ ,]%d ", s1, &x, &y);

%[^, ] => searches for everything except , and <space> and stores it in s1

%*[ ,] => searches for , and <space> but does not store it anywhere (the * ensures that)

%d => stores the number

Why are you using FILE* and friends in C++?

The other answers specify the problem with your code, so I'm writing this answer to show you how to improve it.

std::ifstream file("input.txt");
std::string name, value0, value1;

while (std::getline(file, name, ',')) {

    // Get the value strings from the stream.
    std::getline(file, value0, ',');
    std::getline(file, value1, ',');

    // These will throw an exception when given invalid input.
    int v0 = std::stoi(value0);
    int v1 = std::stoi(value1);

    // Do stuff with the strings
}

std::getline can be used to extract a string from a stream up until a certain delimiter. Whitespaces are ignored here, so we don't have to care about them. The return value of std::getline is the stream passed in, and it has an operator bool() that allows us to use it as a boolean expression. The value will become false when the stream is either empty or in some erroneous state.

Note that the above should be similar in behavior to:

while (file) {
    std::getline(file, name, ',');

    // ...
}

I'm pretty sure this must be a whole lot more readable than a string like "%99[^,],%99[^,],%99[^,]" .

Cheers~

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM