views:

110

answers:

3

I want to read a txt file line by line and after reading each line, I want to split the line according to the tab "\t" and add each part to an element in a struct.

my struct is 1*char and 2*int

struct myStruct
{
    char chr;
    int v1;
    int v2;
}

where chr can contain more than one character.

A line should be something like:

randomstring TAB number TAB number NL
+1  A: 
std::ifstream in("fname");
while(in){
    std::string line;
    std::getline(in,line);
    size_t lasttab=line.find_last_of('\t');
    size_t firsttab=line.find_last_of('\t',lasttab-1);
    mystruct data;
    data.chr=line.substr(0,firsttab).c_str();
    data.v1=atoi(line.substr(firsttab,lasttab).c_str());
    data.v2=atoi(line.substr(lasttab).c_str());
}
flownt
this code gives invalid output!!
sikas
Please lookup why not to use in as the condition of the loop.
Martin York
+3  A: 

Try:
Note: if chr can contain more than 1 character then use a string to represent it.

std::ifstream file("plop");
std::string   line;

while(std::getline(file, line))
{
    std::stringstream   linestream(line);
    std::string         data;
    int                 val1;
    int                 val2;

    // If you have truly tab delimited data use getline() with third parameter.
    // If your data is just white space separated data
    // then the operator >> will do (it reads a space separated word into a string).
    std::getline(linestream, data, '\t');  // read up-to the first tab (discard tab).

    // Read the integers using the operator >>
    linestream >> val1 >> val2;
}
Martin York
+1  A: 

Unless you intend to use this struct for C as well, I would replace the intended char* with std::string.

Next, as I intend to be able to read it from a stream I would write the following function:

std::istream & operator>>( std::istream & is, myStruct & my )
{
    if( std::getline(is, my.str, '\t') )
       return is >> my.v1 >> my.v2;
}

with str as the std::string member. This writes into your struct, using tab as the first delimiter and then any white-space delimiter will do before the next two integers. (You can force it to use tab).

To read line by line you can either continue reading these, or read the line first into a string then put the string into an istringstream and call the above.

You will need to decide how to handle failed reads. Any failed read above would leave the stream in a failed state.

CashCow