0

I have some sample code and I cannot figure out why it's not reading in each line properly. The logic looks fine, but I suspect that it might be some buffer issue in my file object after I read file into num_of_shades.

colors.cpp

#include <iostream>
#include <fstream>
using namespace std;

// holds data for my color(s)
struct Color {
    char color_name[255]; // up to 255 characters
    int num_of_shades;
    char shade[10][255]; // up to 10 shades, 255 characters for each row
};

// holds my Color data structure
struct Box {
    Color color[5]; // up to 5 colors
};

int main() {
    Box b;

    ifstream file;
    file.open("colors.dat");

    int i=0;
    int j=0;

    while(!file.eof()) {
        // can't have more than 5 colors, (index 0 to 4)
        if(i >= 5) {
            break;
        }       


        file.getline(b.color[i].color_name, 255);
        file >> b.color[i].num_of_shades;

        // can't have more than 10 shades
        if(b.color[i].num_of_shades > 10) {
            break;
        }


        for(j=0; j < b.color[i].num_of_shades-1; j++) {
            file.getline(b.color[i].shade[j], 255);
        }

        i++;
        j=0;
    }

    file.close();

    // Print out results (comments to the right are the results I want)
    cout << b.color[0].color_name << endl; // RED
    cout << b.color[0].num_of_shades << endl; // 3
    cout << b.color[0].shade[0] << endl; // Light Red
    cout << b.color[0].shade[1] << endl; // Brick Red
    cout << b.color[0].shade[2] << endl; // Dark Red

    cout << b.color[1].color_name << endl; // BLUE
    cout << b.color[1].num_of_shades << endl; // 2
    cout << b.color[1].shade[0] << endl; // Dark Blue
    cout << b.color[1].shade[1] << endl; // Light Blue
}

colors.dat (how my .dat file looks, and also how I want to print out my data)

RED
3
Light Red
Brick Red
Dark Red
BLUE
2
Dark Blue
Light Blue

./a.out (how the program prints it out)

Red
3

Light Red

Brick Red
0
  • You will want to review [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) Control the read loop with the read itself, e.g. `while (file.getline(b.color[i].color_name, 255) && file >> b.color[i].num_of_shades) { ... }` Then call `file.ignore (...)` – David C. Rankin Jan 26 '20 at 22:03

1 Answers1

1

You are mixing up stream extraction operator >> and getline. >> will read characters up to but not including a whitespace (including newline). getline will read the whole line and discard the newline.

What's happening is that the newline character is read with the first getline for reading shades. Hence the blank line you see in the output of shades. To solve the problem, I would add this line after file >> b.color[i].num_of_shades;:

file.ignore(std::numeric_limits<streamsize>::max(), '\n');

This will ignore everything remaining and the newline after reading the number.

Another issue you have is that you are reading one less the number of shades you have because you are doing for(j=0; j < b.color[i].num_of_shades-1; j++). You need change this to:

for (j = 0; j < b.color[i].num_of_shades; j++) 
jignatius
  • 5,606
  • 2
  • 7
  • 21