Ravi
Ravi

Reputation: 79

Reading a comma separated file into an integer array

Iam trying to read a text file containing integers into an integer array. If the Input is: 1 3 4 5 6 (with space in between) It is working fine.

but if the input is: 1,3,4,5,6 (comma separated) .Its just printing 1.(first digit).If the program finds 1,3,4,5,6 as a single entity then it should print 1,3,4,5,6 as the first index ryt? And also File>>x , does this expression take value one by one by detecting the space in between??

#include<iostream>
#include<fstream>
#include<string>
using namespace std;

int main()
{    
    int n = 0; //n is the number of the integers in the file ==> 12
    int num;
    int arr[100];
    int x;
    int sum = 0;
    ifstream File;
    File.open("integer.txt");
    if(!File.is_open())
    {
        cout<<"It failed"<<endl;
        return 0;
    }

    while(File>>x)
    {
        arr[n] = x; 
        n++;
    }

    File.close();
    cout<<"n : "<<n<<endl;
    for(int i=0;i<n;i++)
    {
        cout << arr[i] << " ";
    }
    return 0;
}

Upvotes: 3

Views: 12019

Answers (4)

Christian Hackl
Christian Hackl

Reputation: 27518

but if the input is: 1,3,4,5,6 (comma separated) .Its just printing 1.(first digit). If the program finds 1,3,4,5,6 as a single entity then it should print 1,3,4,5,6 as the first index ryt?

It prints just "1" because you attempt to read "1,3,4,5,6" into an int object. An int, however, cannot be "1,3,4,5,6". Plainly speaking, parsing stops as soon as the first "bad" character, i.e. the comma, is reached, and you end up with the integer number that has been built up so far, i.e. "1".

The rest of the input is discarded. It's as if your line was "1abcdef", or "1abcdef2345".

And also File>>x , does this expression take value one by one by detecting the space in between??

Yes, and that makes it quite inflexible.

What I recommend instead of fiddling with operator>> is using std::getline, passing ',' as delimiter. While the function's name then no longer makes sense, because it no longer reads lines (as it would with the default delimiter '\n'), it will work just fine.

You will end with up with individual std::string objects which are easy to convert to ints using std::stoi.

While you're at it, get rid of the raw int arr[100] and make it a std::vector<int>, so that you are not limited to 100 elements. 100 is an ugly magic (arbitrary) number, anyway.

Here is an example:

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

int main()
{
    // faking some test file input; behaves like an `std::ifstream`:
    std::istringstream is("1,2,3,4,5");

    std::vector<int> numbers;

    std::string number_as_string;
    while (std::getline(is, number_as_string, ','))
    {
        numbers.push_back(std::stoi(number_as_string));
    }

    std::cout << "n : " << numbers.size() << "\n";
    for(auto&& number : numbers)
    {
        std::cout << number << "\n";
    }
}

As you can see, I've also taken the chance to propose some other good C++ practices, such as avoiding using namespace std and std::endl.

Upvotes: 2

Sam Nolan
Sam Nolan

Reputation: 94

What's happening here is that after the first letter is extracted, your code tries to extract the comma as an integer. As it cant do this, it will return false and end the loop.

There is a very similar question here.

Your while loop should look like this:

while(File>>x)
{
    arr[n] = x; 
    n++;
    if (ss.peek() == ',')
        ss.ignore();
}

Upvotes: 2

KingOfWigs
KingOfWigs

Reputation: 17

Have you tried using sscanf with ifstream? A simple example below

    #include<iostream>
    #include<fstream>
    #include<string>
    using namespace std;

    int main()
    {
        int n = 0; //n is the number of the integers in the file ==> 12
        int num;
        int arr[100];
        char line[200];
        char *ptr=line;
        int x=0,count=0;
        int sum = 0;
        ifstream File;
        File.open("integer.txt");
        if(!File.is_open())
        {
            cout<<"It failed"<<endl;
            return 0;
        }
        File.getline(line,200);

       while((count=sscanf(ptr,"%d,",&x))>0)
        {
            arr[n] = x;
            n++;
            ptr+=count+1;
        }
        File.close();
        cout<<"n : "<<n<<endl;
        for(int i=0;i<n;i++)
        {
            cout << arr[i] << " ";
        }
        cout<<endl;
        return 0;
    }

Upvotes: 0

goldenBoy
goldenBoy

Reputation: 1

Its most likely that when you enter that with commas into the file it is reading it as one whole string. Make sure that theres a delimiter for comma also, I don't know where you would be putting the comma in this code, but you need a delimiter nonetheless.

//example function you can use.
getline( ss, s, ',' )

Upvotes: 0

Related Questions