1

I created a text file love.txt:

i love you
you love me

How do I store them into separate array, namely line1 and line2 and then display them out in console?

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

int main()
{
  string line1[30];
  string line2[30];
  ifstream myfile("love.txt");
  int a = 0;
  int b = 0;
  if(!myfile) 
  {
    cout<<"Error opening output file"<<endl;
    system("pause");
    return -1;
  }
  while(!myfile.eof())
  {
    getline(myfile,line1[a],' ');
    cout<<"1."<<line1[a]<<"\n";
    getline(myfile,line2[b],' ');
    cout<<"2."<<line2[b]<<"\n";
  }
}
Mat
  • 202,337
  • 40
  • 393
  • 406
newbieprogrammer
  • 848
  • 7
  • 23
  • 46
  • 1
    If you are really trying to write C++ code, maybe you should consider using std::vector instead of those `evil` arrays... – Mihai Todor Jul 18 '12 at 16:37
  • std::vector std wasnt taught in my lesson yet and I dun know how to use them. – newbieprogrammer Jul 18 '12 at 16:39
  • I see. Well, it's dead simple, but if you can't use them, then you need a counter which increments after each call to `getline` in the while loop. You should use a multidimensional array like matrix[2][30] and then you will insert your string in matrix[counter]. If the teacher sticks to arrays and pointers, maybe he should specify that the course is about C, not C++. If you're curious about std::vector, well, it allows you to do something like this: `std::string data; cin >> data; vector.push_back(data);` inside the loop. Then you can just iterate over the vector to print it. – Mihai Todor Jul 18 '12 at 16:50
  • Oh, I just noticed that you use string instead of char *. My rant above applies to char *matrix[2][30]. Just follow Attila's suggestion, after you read a decent C++ tutorial... The `using namespace std;` statement is not there for nothing ;) – Mihai Todor Jul 18 '12 at 16:53

4 Answers4

6

Try specifying the last argument as '\n' in both getline() functions:

getline(myfile, line1[a], '\n');

instead of

getline(myfile, line1[a], ' ');
Chris
  • 332
  • 3
  • 8
Mahesh Meniya
  • 2,627
  • 3
  • 18
  • 17
6

How about this.. .

vector <string> v;
string line;    
ifstream fin("love.txt");
while(getline(fin,line)){
    v.push_back(line);
}
2

You can think of a string as an array of characters, so you will only need one array of strings:

const size_t SIZE = 30;
string line[SIZE]; // creates SIZE empty strings
size_t i=0;
while(!myfile.eof() && i < SIZE) {
  getline(myfile,line[i]); // read the next line into the next string
  ++i;
} 

for (i=0; i < SIZE; ++i) {
  if (!line[i].empty()) { // print only if there is something in the current line
    cout << i << ". " << line[i];
  }
}

You could maintain a counter to see how many lines you have stored into (instead of checking for empty lines) as well -- this way you will properly print empty lines as well:

const size_t SIZE = 30;
string line[SIZE]; // creates SIZE empty strings
size_t i=0;
while(!myfile.eof() && i < SIZE) {
  getline(myfile,line[i]); // read the next line into the next string
  ++i;
}
size_t numLines = i;

for (i=0; i < numLines; ++i) {
  cout << i << ". " << line[i]; // no need to test for empty lines any more
}

Note: you will be able to store only up to SIZE lines. If you need more, you will have to increase SIZE in the code. Later on you will learn about std::vector<> that allows you to dynamically grow the size as needed (so you won't need to keep track of how many you stored).

Note: the use of constants like SIZE allows you to change the size in one place only

Note: you should add a check for errors in the input stream on top of eof(): in case there was a read failure other than reaching the end of the file:

while (myfile && ...) {
  // ...
}

here myfile is converted to a boolean value indicating if it is OK to use it (true) or not (false)


Update:

I just realized what you are after: you want to read the input as series of words (separated by space), but display them as lines. In this case, you will need arrays-of-arrays to store each line

string line[SIZE1][SIZE2];

where SIZE1 is the maximum amount of lines you can store and SIZE2 is the maximum amount of words you can store per line

Filling this matrix will be more complex: you will need to read the input line-by-line then separate the words within the line:

string tmp; // temporary string to store the line-as-string
getline(myfile, tmp);
stringstream ss(tmp); // convert the line to an input stream to be able to extract
                      // the words
size_t j=0; // the current word index
while (ss) {
  ss >> line[i][j]; // here i is as above: the current line index
  ++j;
}

Output:

for (i=0; i < numLines; ++i) {
  cout << i << ". ";
  for (size_t j=0; j < SIZE2; ++j) {
    if (!line[i][j].empty()) {
      cout << line[i][j] << " ";
    }
  }
}
Attila
  • 28,265
  • 3
  • 46
  • 55
  • @MihaiTodor - yes, I realized it during my later edits, should be fixed now – Attila Jul 18 '12 at 17:01
  • thanks but those code are too advance for me.... declaration such as "const size_t" is new to me.. – newbieprogrammer Jul 18 '12 at 17:11
  • @user1526669 - `const` means you cannot change the value -- protects you from some coding mistakes (you can leave it out if you have not learned this feature yet); `size_t` is an unsinged (non-negative) integer -- I used it as the line numbers cannot be negative (you can use `int` just as well if you don't know `size_t` yet); The updated version uses `std::stringstream`, which will most likely too advanced for you, but I cannot think of a more basic way to achieve the extraction otherwise, sort of going through the input line character by character and that will be messy – Attila Jul 18 '12 at 17:15
  • with this \n it solved my beginner problem, the approach suggested above hasnt been taught so it would be pretty difficult for me to apply them. thx – newbieprogrammer Jul 19 '12 at 02:06
1

My complete solution.

the config.txt file contains:

#URL WEB POP3 IMAP SMTP FTP DNS PING ORDER
st-xxxx.com 1 1 0 1 1 0 1 1
24.xxx.195.11 1 1 0 1 1 0 1 2
24.xxx.195.12 1 1 0 1 1 0 1 3
192.168.0.100 1 1 0 1 1 0 1 4

and my code:

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

using namespace std;

int main()
{

  ifstream myfile("config.txt");
  if(!myfile)
  {
    cout<<"Error opening output file"<<endl;
    system("pause");
    return -1;
  }

    const size_t SIZE1 = 30;
    const size_t SIZE2 = 10;
    string line[SIZE1][SIZE2];

    string tmp; // temporary string to store the line-as-string

    size_t i=0; // the current line index
    size_t j=0; // the current word index


    while(!myfile.eof() && i < SIZE1) {
    getline(myfile, tmp);
    stringstream ss(tmp); // convert the line to an input stream to be able 
//to extract the words
    size_t j=0;
    while (ss) {
      ss >> line[i][j]; // here i is as above: the current line index
      ++j;
    }
    i++;
    }

    size_t numLines = i;

    cout << numLines << "\n";
for (i=1; i <= numLines; ++i) {

  for (size_t j=0; j < SIZE2; ++j) {
    if (!line[i][j].empty()) {
      cout << line[i][j] << " ";
    }
  }
  cout << "\n";
}
    cout << line[3][0] << "\n"; // print the third line first word
}

Hope tht helps anybody who is searching for this type of solution, even if the post is quite old.