-1

I have a .txt file and I'm expecting to get a certain line format from it that contains data that I need to keep.

For instance:

input.txt:

Number: 654
Name: Alon
-----

I need to:

1. extract the 654 and "Alon" into their appropriate variables.

2. throw an error if the format is not exact.

If this was C I would probably use:

if (fscanf(inputFile, "Number: %d", &num) == 0)
{
    // raise an error
}

Assuming using C's functions are not a good idea, I'm left with std::cin that might give me access to the data that I need to extract, but no control over the exact format of the string wrapping the data.

I have already opened and read the file as an "ifstream" using . I've also retrieved the first line using std::getline(...). This is what I've got:

std::ifstream inputFile;
string lineToParse;
inputFile.open("input.txt", std::fstream::in);
if (inputFile.fail())
{
    // throw exception
}
else
{
    std::getline(inputFile, lineToParse);
    int data;
    inputFile >> data;
}

Assuming input.txt is the file above, I expect lineToParse to be "Number: 654" and data to be 654. But as I said, I gain no control over the format of the line this way.

Any ideas?

  • What have you tried? Have you attempted to open the text file and read it using ``? – GKE Sep 05 '18 at 21:26
  • 5
    [`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) is probably going to make its way in to your code sooner or later. – WhozCraig Sep 05 '18 at 21:26
  • Editing my question to make it clearer: I opened and read the file as an "ifstream", and I retrieved the first line using "std::getline". – Alon Emanuel Sep 05 '18 at 21:28
  • Use it *again*. this time by wrapping the line you read into a [`std::istringstream`](https://en.cppreference.com/w/cpp/io/basic_istringstream), and sucking data in delimited by `:`. If the resulting *word* matches one of your predefined labels, you're on your way. There are other ways of doing this; this approach isn't some magic bullet. But it would probably suffice for you – WhozCraig Sep 05 '18 at 21:32
  • @drescherjm, I've edited my code in. – Alon Emanuel Sep 05 '18 at 21:40
  • 2
    You need a while loop like this: `while (std::getline(inputFile, lineToParse)) {` And then do what @WhozCraig said with lineToParse in the loop. – drescherjm Sep 05 '18 at 21:43
  • 1
    Possible duplicate of [Read file line by line in C++](https://stackoverflow.com/q/7868936/608639), [Parsing key/value pairs from a string in C++](https://stackoverflow.com/q/27006958/608639) and [Split string into key-value pairs using C++](https://stackoverflow.com/q/38812780/608639) – jww Sep 06 '18 at 00:03

1 Answers1

2

You can use std::getline to parse up to a specific character like ':'.

Something like:

int line_number = 0;
while(std::getline(inputFile, lineToParse))
{
    ++line_number;

    // check for empty lines here and skip them

    // make a stream out of the line
    std::istringstream iss(lineToParse);

    std::string key, value;
    if(!std::getline(std::getline(iss, key, ':') >> std::ws, value))
    {
        std::cerr << "bad format at line: " << line_number << '\n';
        continue;
    }

    // do something with key and value here...
}

One you have your key and value the key should tell you how to convert the value (be it integer, float, date/time etc...).

Galik
  • 47,303
  • 4
  • 80
  • 117