1

I am trying to parse a Class data from a txt file in C++. The Class data looks like this, contains some datetime string, some integer and some int.

The data in the txt file looks like this:

2014-08-01 02:06:53,3.9070,9

How to parse the data from the file into the Class?

Problems faced: 1) getting the input from the file for the datetime 2) separating the datetime input from the other data input.

lakshmen
  • 28,346
  • 66
  • 178
  • 276
  • If you're lucky you are on a system with a [`strptime`](http://man7.org/linux/man-pages/man3/strptime.3.html) function. Otherwise there are [alternatives](http://stackoverflow.com/questions/321849/strptime-equivalent-on-windows). – Some programmer dude Aug 15 '14 at 05:15
  • And you don't need the `!in.eof()` in your loop condition, it's redundant. – Some programmer dude Aug 15 '14 at 05:16
  • 1
    Or am I misunderstanding you? The way you read the date-time string from the file does not follow the format you give in the question at all. Instead you construct a string of that format and store in the class. My question is of course why you want to store a date-time stamp internally *as text*? You should read the data-time stamp as text, then parse it into a binary time-stamp than can be used by the C or C++ standard functions, preferably in a [C++11 `chrono` object](http://en.cppreference.com/w/cpp/chrono). – Some programmer dude Aug 15 '14 at 05:19
  • And considering that you store the data-time as a string in the structure, what does `Datetime::Parse` do? Parse from a string into a binary time-stamp, then convert that back into a string again? – Some programmer dude Aug 15 '14 at 05:34
  • As for the format in the file, please show a *complete* and *unmodified* record. Does it contain newlines? Is it comma-separated between fields? And what is the *actual* format for the date-time? – Some programmer dude Aug 15 '14 at 05:35
  • date-time format is locale dependend, that's the whole problem. If everyone used the same date-time - you will never get such a question. For example my date time is: $ date Пт авг 15 10:44:34 UZT 2014 – Tanuki Aug 15 '14 at 05:44
  • how to find datetime format for my computer? – lakshmen Aug 15 '14 at 05:46

1 Answers1

4

You have multiple problems, most of them regarding your reading and parsing:

  • Each record (each line) contains three values: A date-time stamp, and two numeric values. You read the date-time stamp (wrongly, I'll come back to that) and then you read six more values.

  • When you read the numeric values, you read them into a temporary buffer, but then you use the input stream to assign to the structure fields.

  • Nowhere in the reading you handle the comma that separates the values.

  • As with the comma, you read the date-time without consideration of the separators in the date-time format.

  • You read the date-time field into separate values, then create a string of the exact same format as in the file. That's not really needed (I will tell you why below).

  • The date-time is stored in the structure as a string, so why are you trying to parse it, if you're just storing it in a string anyway? What, if anything, does the DateTime::Parse function really do?


Now to help you with your problem there are a couple of things in the C++ standard library that can help you. The first is the std::getline function, the second is std::istringstream.

First of all I suggest you read each line from the file complete (using std::getline), put the line into a std::istringstream and use that for the parsing, again using std::getline.

Something like

std::string line;
while (std::getline(in, line))
{
    std::istringstream iss(line);

    // Parse each line using the input string stream
}

The std::getline by default uses the newline as separator, but it can be told to use any single character, for example ',': Also note that I put the date-time string directly into your structure.

std::getline(iss, item->datetime, ',');

The above two lines will put the complete date-time string into the datetime member variable. You can then get the two other values easily the same way:

std::string temp;

std::getline(iss, temp, ',');
item->open = std::stod(temp);

std::getline(iss, temp);  // Last item in input, no need for separator
item->volume = std::stoi(temp);

(Read about std::stod and std::stoi.)

I randomly picked two member fields from your structure to initialize, because there are only two numeric fields per record in the file.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621