What I want to do is read a line from text file which contains a two word string which has a length <= 20 and two integers, for example it may look something like this:
Name Surname 1 14
I know that if I read string, the string will be all characters until the white space, however getline() reads the whole line as a string. So how do I read a line like this ? Is there any easy way or I will have to use regular expressions ?
Maybe...
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream file( "/home/facu/text.txt", ios::in );
string part1, part2;
int num1, num2;
if( !file )
cerr << "Cant open " << endl;
while( file >> part1 >> part2 >> num1 >> num2 )
{
cout << part1 << " " << part2 << " " << num1
<< " " << num2 << endl;
}
file.close();
return 0;
}
Where text.txt:
JONES JONES 12 14
MICHAEL MICHAEL 12 100
DOE DOE 15 20
std::getline()
is probably the best function for this. Then create some form of parser which delimits each field by whitespace. From there, you can use std::stringstream
to convert the fields (in this case 2 and 3 if starting at 0) to integer values. You will obviously want to do some sort of error handling for any sort of I/O operation.
EDIT: Here is an example which my help you get started
// Example
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#define FIELD_SIZE 4 // How many fields per line
// This is just a custom data structure to hold the data you want
struct myInfo
{
myInfo(){} // Default ctor
myInfo(std::string name1,std::string name2,int n1,int n2) // Ctor accepting all data
: first(name1), last(name2), num1(n1), num2(n2) {}
std::string first, last;
int num1,num2;
};
// Get the initial size of what your array should be
// This is based on how many '\n's are found
int getNumLines(const std::string& input)
{
int retval = 0;
for(unsigned int i=0;i<input.length();++i)
if(input[i] == '\n')
retval++;
return retval;
}
// Convert string to int
int convertStringToInt(const std::string& input)
{
std::stringstream ss(input);
int retval;
ss >> retval;
return retval;
}
// Parse input and store it in our structure
// Not really efficient if you have large datasets to work with
void parseAndStore(std::string input, myInfo *& myArray, int size)
{
size_t pos = 0, pos2 = 0; // Temporary position holder
std::string first, last, tmp1, tmp2;
std::stringstream tmp;
int num1, num2;
// This is not efficient - it's merely an example
for(int i=0;i<size;++i) // How many items to insert
for(int j=0;j<FIELD_SIZE;++j) // How many fields
{
if(j < FIELD_SIZE-1)
{
pos2 = input.find(" ",pos+1);
if(pos2 == std::string::npos || pos2 > input.find('\n',pos)) // Don't run over the next line
{
pos = input.find('\n',pos); // Next line
break; // Error - invalid line format
}
// Relatively hacky, but this is just an example to give you an idea
switch(j)
{
case 1:
last = input.substr(pos,pos2-pos);
break;
case 2:
tmp1 = input.substr(pos,pos2-pos);
break;
default:
first = input.substr(pos,pos2-pos);
break;
}
pos = pos2+1;
} else { // All data collected - parse our ints and store it in our structure
pos2 = input.find('\n',pos); // End of line
tmp2 = input.substr(pos,pos2);
// Convert
num1 = convertStringToInt(tmp1);
num2 = convertStringToInt(tmp2);
// Insert it into our array
myArray[i] = myInfo(first,last,num1,num2);
pos = pos2+1; // Advance position
}
}
}
int main()
{
// Read your input file - this is just an example
std::string input("Joe Serma 1 30\nGeorge Hola 2 17\n");
int size = getNumLines(input); // Parse the number of lines in your input
myInfo * myArray = new myInfo[size]; // Allocate a dynamic array to store your data
parseAndStore(input,myArray,size); // Parse this string - leave the original in tact though
// Print contents of the array
for(int i=0;i<size;++i)
{
std::cout<< std::endl << "=== Person "<< i+1 << "===" << std::endl
<< "First: "<< myArray[i].first << std::endl
<< "Last: "<< myArray[i].last << std::endl
<< "Num1: "<< myArray[i].num1 << std::endl
<< "Num2: "<< myArray[i].num2 << std::endl
<< "Num1+Num2 (For confidence of true int): "<< myArray[i].num1+myArray[i].num2 << std::endl;
}
delete [] myArray; // Cleanup
return 0;
}
Regards,
Dennis M.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With