Reputation: 79
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
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 int
s 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
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
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
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