2

I've used C# and Java, so I'm used to opening an input file and reading until the end of the file stream while using some sort of .split on each line with the delimiter as a tab, comma, etc. to get the individual values OR extracting the a specific number of characters for each value. I recently began taking a C++ class and haven't had any problems with the assignments so far because they were mostly using console input/output, but I'm finding it rather difficult to extract data from a file:

struct Student{
    string _fullName[50];
    int _grade;
    float _avg;
};

int main(){

    Student students[30];

    ifstream inputFile;
    inputFile.open("file.txt");
    if (inputFile.is_open()){
        int i = 0;

        char data[100];
        while (inputFile.getline(data, 100)){
           //need to split the data by \t and properly convert it into an int/string/float where needed
        }

    }
    system("pause");
    return 0;
}

I considered changing the getline delimiter to \t and setting each value that way (i.e., resetting i to 0 after the 3 properties have been set), but this won't work if one of the lines is missing a value. That won't matter in this small assignment, but I'm looking to do this correctly and efficiently. What's the most efficient way to extract the data on each line and correctly parse it into the appropriate data type?

Note: I'm not supposed to be using vectors or algorithms at this point.

  • 3
    "I'm not supposed to be using vectors or algorithms at this point." sounds like you have one of those teachers who believes a c++ class should start with C, not C++. what a shame. that's just not how c++ should be taught. for more: https://www.youtube.com/watch?v=YnWhqhNdYyk – johnbakers May 14 '16 at 20:47

1 Answers1

1

I would suggest stringstream. You're already using standard streams, so I don't think it would be off-topic (and if it's, looks like you're supposed to write your own string splitter). stringstream works exactly like ifstream but it reads from a memory buffer instead of file:

#include <sstream>
// ...

char data[100];
while (inputFile.getline(data, 100)){
   std::stringstream lineStream(data);
   while (lineStream >> data) {
     // now you have a token (space-delimeted) in 'data'
   }
}

You can also split by commas and arbitrary delimiter with getline

Community
  • 1
  • 1
yeputons
  • 8,478
  • 34
  • 67
  • Is is better to use `std::string` instead of `char data[100]`: `getline(inputFile, str);` – Dmitriy Zapevalov May 14 '16 at 21:08
  • @DmitriyZapevalov yes, absolutely - `std::string` is better than manual memory management. I haven't noticed that there is a `string` in the original question already. – yeputons May 14 '16 at 21:10
  • I replaced `char data[100]` with `string data`, but shouldn't I create another variable like `string temp` and replace `lineStream >> data` with lineStream >> temp in order to read the data since data is storing the entire line? I did this and it seems to be working, but I wanted to make sure I'm not misunderstanding your example. –  May 14 '16 at 21:54
  • @Dinerdo there is no need in extra variables - stringstream copies data into its internal buffer and afterwards you can re-use the variable which stored line if you want. – yeputons May 14 '16 at 22:02
  • only space delimit it ? no other can be even if just tab? –  Jan 02 '20 at 12:58
  • @nonock tabs should work as well, I believe, just like with `ifstream` – yeputons Jan 04 '20 at 22:01