0

I'm trying to populate a 2D char array from a text file that looks like:

Bob
Jill
Mike
Steven

and I'm not sure how to do this with different lengths of characters in each line. Here is my code:

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


int main(){
    char names[4][7];
    string fileName = "names.txt";
    ifstream inFile(fileName);

    while(!inFile.eof()){
        for(int i=0; i<4; i++){
            for(int j=0; j<7; j++){
                inFile.get(names[i][j]);
            }
        }
    }

    for(int i=0; i<4; i++){
        for(int j=0; j<7; j++){
            cout << names[i][j];
        }
    }

    return 0;
}

and this will print

Bob
Jill
Mike
Steven????????

Where each ? is just a gibberish character. I'm pretty sure this is happening because each line of the text file isn't 7 char long, so it's trying to fill the the rest of the array. What is the correct way to do this? I thought the while(!inFile.eof()){} would stop this.

TheStrangeQuark
  • 1,704
  • 2
  • 18
  • 46
  • 2
    2D arrays of char are rarely a sensible way of dealing with strings (you probably want a std::vector of std::striing) and also see https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong –  Jan 21 '18 at 02:23
  • `while(!inFile.eof()){` -- Read why [using istream::eof() is considered wrong](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – PaulMcKenzie Jan 21 '18 at 02:40

2 Answers2

1

Since you're using C++, you'll want to use string and vector.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;
int main()
{
    ifstream file("file");
    string line;
    vector<string> names;

    if (file.is_open())
        while (getline(file, line))
            names.push_back(line);

    for (auto it = names.begin(); it != names.end(); ++it)
        cout << *it << '\n';

    return 0;
}
O'Neil
  • 3,638
  • 3
  • 13
  • 28
Edward Karak
  • 10,340
  • 8
  • 41
  • 68
0

The problem with you C-array, and fixed loops size, can be highlighted by adding braces here:

for(int i=0; i<4; i++){
    std::cout << '{';
    for(int j=0; j<7; j++){
        cout << names[i][j];
    }
    std::cout << '}';
}

Which will print:

{Bob
Jil}{l
Mike
}{Steven<garbage>}{<garbage>}

Indeed, your names are stored like:

char names[4][7] {
    {'B', 'o', 'b','\n', 'J', 'i', 'l'},
    {'l','\n', 'M', 'i', 'k', 'e','\n'},
    {'S', 't', 'e', 'v', 'e', 'n', <garbage>},
    {<garbage>}
};

See stackptr's answer for correction.

O'Neil
  • 3,638
  • 3
  • 13
  • 28