Reputation: 43
I am trying to get a txt file with entries part1/1 part2/4 etc... from user and store in vectors "part_name" and "rev_id". So "part_name" contains part1 part2 ... and "rev_id" contains 1 4..... The program is run as program.exe list.txt in command prompt.
The program works fine when the txt file has 2 or more inputs , but when it has single input the vector
size is shown as 2 (but must be 1).
i.e.
if list.txt
contains part1
/1
part2
/4
=> part_name.size()
is 2
if list.txt
contains part1
/1
=> part_name.size()
is still 2.
Can someone help me resolve this ?
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
int main(int argc, char*argv[])
{
std::string s ;
std::string delimiter = "/";
size_t pos;
std::vector<std::string> part_name;
std::vector<std::string> rev_id;
std::string token1,token2;
ifstream readFile (argv[1]);
if (readFile.is_open())
{
while (!readFile.eof())
{
readFile >> s;
pos=s.find(delimiter);
if((pos!=std::string::npos)&&(pos!=0))
{
token1 = s.substr(0, s.find(delimiter));
token2 = s.substr(pos + delimiter.length());
part_name.push_back(token1);
rev_id.push_back(token2);
}
}
}
else{
std::cout<<"Cannot open file"<<endl;
}
readFile.close();
for (unsigned j=0; j < part_name.size(); j++)
{
cout<<part_name.size()<<endl;
cout<<"part name j is " <<part_name[j]<<endl;
cout<<"part id j is " <<rev_id[j]<<endl;
}
}
Upvotes: 0
Views: 68
Reputation: 3044
eof()
returns true not when the file position is at the end, but after you attempt a read at the end of the file. So the first time in the loop you consume the input up to the eof (not included). Now eof()
is false. For this reason the loop is entered again and this time the extractor (>>) hits the end of file. The read operation fails and the string is not changed (that's why you see the same values twice).
A better (and more idiomatic to modern C++) way to code is by using stream iterators
#include <iterator>
// [...]
std::istream_iterator<std::string> scan( readFile );
std::istream_iteartor<std::string> eof;
while( scan != eof )
{
s = *scan++;
// s is your string
}
Also it would be better to have the loop in the second part to run from 0 upward, since elements in vectors are numbered starting from 0.
Upvotes: 1
Reputation: 1729
Your last read is probably not reading anything. Try:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
int main(int argc, char*argv[])
{
std::string s ;
std::string delimiter = "/";
size_t pos;
std::vector<std::string> part_name;
std::vector<std::string> rev_id;
std::string token1,token2;
ifstream readFile (argv[1]);
if (readFile.is_open())
{
while( ( readFile >> s ).good() )
{
std::cerr << "Field '" << s << "' and " << readFile.good() << std::endl;
pos=s.find(delimiter);
if((pos!=std::string::npos)&&(pos!=0))
{
token1 = s.substr(0, pos);
token2 = s.substr(pos + delimiter.length());
part_name.push_back(token1);
rev_id.push_back(token2);
}
}
}
else {
std::cout<<"Cannot open file"<<endl;
}
readFile.close();
for (unsigned j=0; j < part_name.size(); j++)
{
cout<<part_name.size()<<endl;
cout<<"part name j is " <<part_name[j]<<endl;
cout<<"part id j is " <<rev_id[j]<<endl;
}
}
Upvotes: 1
Reputation: 785
I think the problem lies here
while (!readFile.eof())
{
readFile >> s;
pos=s.find(delimiter);
if((pos!=std::string::npos)&&(pos!=0))
{
token1 = s.substr(0, s.find(delimiter));
token2 = s.substr(pos + delimiter.length());
part_name.push_back(token1);
rev_id.push_back(token2);
}
change above to
while (readFile >> s)
{
pos=s.find(delimiter);
if((pos!=std::string::npos)&&(pos!=0))
{
token1 = s.substr(0, s.find(delimiter));
token2 = s.substr(pos + delimiter.length());
part_name.push_back(token1);
rev_id.push_back(token2);
}
Upvotes: 3
Reputation: 2073
There are some lines than make me suspicious.. Why start your iteration loop by the index 1 ?
for (unsigned j=1; j < part_name.size(); j++)
{
cout<<part_name.size()<<endl;
cout<<"part name j is " <<part_name[j]<<endl;
cout<<"part id j is " <<rev_id[j]<<endl;
}
You always skip the first element of yours vectors.
Upvotes: 0