0

I was told to use a 2D array that reads all the contents of file below and stores it in a 2D array. Here is the file:

People often say that motivation doesn  t last   Well   neither does bathing that s why we recommend it daily   Ziglar
Someday is not a day of the week      Denise Brennan  Nelson
Hire character   Train skill      Peter Schutz
Your time is limited   so don t waste it living someone else s life      Steve Jobs
Sales are contingent upon the attitude of the salesman      not the attitude of the prospect      W   Clement Stone
Everyone lives by selling something      Robert Louis Stevenson
If you are not taking care of your customer   your competitor will      Bob Hooey
The golden rule for every businessman is this: Put yourself in your customer s place      Orison Swett Marden
If you cannot do great things do small things in a great way    Napoleon Hill

*above is a text file containing data

The file has lots of random spaces but I can just use cin to ignore them. The part I am confused about is that each row has different amount of columns to process so I can't simply use a nested for-loop.

At the end I want to be able to cout << data[0][1]; and it should print out "often". Row is essentially the line number of the word.

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56
  • 4
    Learn about [`std::vector`](https://en.cppreference.com/w/cpp/container/vector), [`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) and [`std::istringstream`](https://en.cppreference.com/w/cpp/io/basic_istringstream). – Some programmer dude Dec 12 '19 at 10:04
  • You can dynamically allocate arrays using `new` keyword. Then you would just create an array of pointer to dynamically created arrays. – Marcin Poloczek Dec 12 '19 at 10:12
  • @MarcinPoloczek `new` is bad for good style. At best, it's banned completely from your self-written code. (See the other comment.) – Scheff's Cat Dec 12 '19 at 10:15
  • @Scheff I know, but the question is how to do it using arrays and proper standard approach has already been mentioned in the comment above mine. – Marcin Poloczek Dec 12 '19 at 10:47

1 Answers1

1

You can use getline and then stringstream to read the words.

#include <fstream>
#include <sstream>
#include <string>

using namespace std;

int main() {
    ifstream input;
    string line;
    string word;
    string data[3][10]; //You need to dynamically allocate memory if you don't know the size of your input. I am doing this to keep it short

    input.open("input.txt");

    int i = 0;
    while(getline(input, line)) { //Reading file line by line until the end of file
        stringstream ss(line);
        int j = 0;
        while(ss) {
            ss >> word; //word will become the next string in your line (People, often, say...)
            data[i][j] = word;
            j++;
        }
        i++;
    }

    return 0;
}

And you will get

cout << data[0][0] -> "People"
cout << data[0][1] -> "often"
.
.
etc.
Ayro
  • 42
  • 5
  • 1
    `while (ss)` is just as bad as `while (!ss.eof())` which you [shouldn't do](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons). With the help of [`std::istream_iterator`](https://en.cppreference.com/w/cpp/iterator/istream_iterator) and `std::vector` you don't even need that loop. – Some programmer dude Dec 12 '19 at 10:40
  • Yes, works! thank you. That's very interesting so after it's done reading the sentence and importing all of the words; it adds 1 to counter `i` and that's how it keeps track of the rows – Gorav Soni Dec 12 '19 at 10:51
  • Same thing happens with ss too and you can use while(ss >> word) instead of while(ss) { ss>> word; } to prevent this. If you want to avoid getline reading one more time too you can use if(input.eof()) {break;} at the end of your while or before i++ – Ayro Dec 12 '19 at 11:19
  • Really? ````string data[3][10];````? With magic numbersd? Use a ````std::vector>```` instead. Do not use plain C-Style arrays. – A M Dec 12 '19 at 19:11