3

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;
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Ravi
  • 79
  • 1
  • 2
  • 5

4 Answers4

2

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();
}
Community
  • 1
  • 1
Sam Nolan
  • 94
  • 7
2

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.

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
0

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, ',' )
0

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;
    }
KingOfWigs
  • 17
  • 4
  • The ptr+=count+1 is to skip over the delimiter – KingOfWigs Dec 03 '16 at 09:43
  • Because the OP is using C++ and not C, and `sscanf` is dangerous and type-unsafe. You also added another magic-number array `char line[200]`, needlessly complicated the code with a confusing pointer variable and used the `getline` member function, all of which is very bad coding style. – Christian Hackl Dec 03 '16 at 15:20