Search code examples
c++filetextfstreamifstream

Simple read from text file algorithm doesn't work


I have a text file that contains keys and values like this:

keyOne=1
keyTwo=734
keyThree=22.3
keyFour=5

The keys are just lower-case and upper-case letters like in my example. The values are either integers or floats. Each key and value is separated by an equals sign (=). Now I want to read the values into variables I have in my program.

This is the code I have tried to read the values: (I omitted the part where I store the values in my program's variables, and just print them out now for demonstration.)

std::fstream file(optionsFile, std::fstream::in);

if (file.good()) {
  int begin;
  int end;
  std::string line;

  while(std::getline(file, line)) {

    // find the position of the value in the line
    for (unsigned int i = 0; i < line.length(); i++) {
      if (line.at(i) == '=') {
        begin = i + 1;
        end = line.length();
        break;
      }
    }

    // build the string... it starts at <begin> and ends at <end>
    const char *string = "";
    for (int i = begin; i < end; i++) {
      string += line.at(i);
    }

    // only gibberish is printed in the following line :(
    std::cout << "string=" << string << std::endl;
  }
}

I don't understand why it won't print the value.. instead only weird stuff or even nothing is printed

Please help this broke my spirit so hard :(


Solution

  • You are using C-style strings (char arrays) without properly allocated memory, and you are just manipulating with the pointer, so you are not appending characters into your string:

       // build the string... it starts at <begin> and ends at <end>
    const char *string = "";
    for (int i = begin; i < end; i++) {
      string += line.at(i);
    }
    

    Use std::string instead:

    /// build the string... it starts at <begin> and ends at <end>
    std::string str;
    for (int i = begin; i < end; i++) {
      str += line.at(i);
    }
    

    Or allocate memory by hand, use the proper indexing, terminate the string with '\0' character and don't forget to delete the string after you don't need it anymore:

    char *string = new char[end - begin + 1];
    int j = 0;
    for (int i = begin;  i < end; i++) {
      string[j++] = line.at(i);
    }
    
    // Don't forget to end the string!
    string[j] = '\0';
    
    // Don't forget to delete string afterwards!
    delete [] string;
    

    So, just use std::string.

    Edit Why did you mix C strings and std::string in the first place?