简体   繁体   中英

Wired output by using getline function to read file

My program is to read a file which contains some sales records and separate the time, date, price, volume and the rest. Then store each of them in a vector, respectively. The all records are:

10/10/2013 04:57:27 PM,5.81,5000,29050.00,LT XT

10/10/2013 04:48:05 PM,5.81,62728,364449.68,SX XT

10/10/2013 04:10:33 PM,.00,0,.00,

10/10/2013 04:10:33 PM,.00,0,.00,

10/10/2013 04:10:33 PM,.00,0,.00,

5 rows.

Then my code is:

void main()
{
vector<string> date, time, price, volume, value, condition;
int len;

load(date,time,price,volume,value,condition);

len = date.size();

for (int i=0 ; i<len ; i++)
{
    cout << date[i] << endl;
}

cout << "****************************" << endl;

for (int i=0 ; i<time.size() ; i++)
{
    cout << time[i] << endl;
}

}

The definition for function load is:

void load(vector<string> &object1,
vector<string> &object2,
vector<string> &object3,
vector<string> &object4,
vector<string> &object5,
vector<string> &object6)
{   
    string str1,str2,str3,str4,str5,str6;
    string filename;
    cout << "Enter name of file to read (one word only): ";
    cin >> filename;

ifstream fptr(filename);
if (fptr.rdstate() == 0) // no error open file
{   
    while (!fptr.eof()) 
    { 
        getline(fptr,str1,' ');
        object1.push_back(str1);

        getline(fptr,str2,',');
        object2.push_back(str2);

        getline(fptr,str3,',');
        object3.push_back(str3);

        getline(fptr,str4,',');
        object4.push_back(str4);

        getline(fptr,str5,',');
        object5.push_back(str5);

        getline(fptr,str6,',');
        object6.push_back(str6);
    }
}
else
{  
    cerr << "Could not open file \"" << filename << "\" for reading." << endl; 
}

cout << "- after load function" << endl;
}

Then I get the wired result which is below. I don't know where i am wrong.

result for vector date (4 results which should be 5 and mix up everything):

10/10/2013

5.81,62728,364449.68,SX

.00,0,.00

10/10/2013

result for vector time (same problem):

04:57:27 PM

XT

10/10/2013 04:10:33 PM

04:10:33 PM

You never do a getline with a '\\n' as terminator, so this will be read exactly like any other character, as part of the "line".

My personal preference here would be to loop reading a complete line at a time then use std::regex (or boost::regex ) to separate it up into fields. This ensures that if anything does go wrong in one line, you're immediately resynchronized correctly on the next line.

In other words, the first time you call load , when you read the condition (the last field), you read "LT XT\\n10/10/2013 04:48:05 PM" . And the next call to load , when you try to get the date, you will read "5.81,62728,364449.68,SX" , that is to say, up until the next blank.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM