0

Basically, I'm reading a file and trying to store the data in a 2D, for the differentiation between rows and columns I use the logic below:

    int rows=0,column=0;
    char arr[50][50];
    while(my_file.eof()==0){
        my_file.get(ch);
        if(ch=='\n'){
            rows++;
        }
        arr[rows][column]=ch;
        column++;
    }
for(int j=0;j<rows;j++){
    for(int k=0;k<column;k++){
    cout<<arr[j][k];}
}

But the when I run It shows the following output: https://i.stack.imgur.com/XzhST.png And the text file data is:

  I am going to school
  hi!
  Hello

guide me a bit...

M k.
  • 1
  • 1
  • Wouldn't it be easier to use a `std::vector` and use [`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) to populate the vector? At least then you wouldn't have to worry about the null terminator, or each line having a different length, or forgetting to reset the `column` when you go to a new row. – Some programmer dude Oct 29 '21 at 11:31
  • Also please read [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – Some programmer dude Oct 29 '21 at 11:34
  • What is the purpose of this? Why a 2D array? Do you want to read a file just to print it? – A. Smoliak Oct 29 '21 at 11:36
  • And a short session with a *debugger*, stepping through the code statement by statement while monitoring variables and their values, should have helped you detect some of the mistakes quite quickly. – Some programmer dude Oct 29 '21 at 11:37
  • Oh, and *please* don't post images of text. Copy-paste all text as text into your questions. Even output in a console. Please take some time to read (or refresh) [the help pages](http://stackoverflow.com/help), take the SO [tour], read [ask], as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Oct 29 '21 at 11:38
  • It's a requirement that I use an 2D otherwise doing this with vector is quite well managed – M k. Oct 29 '21 at 11:55
  • Then 1) Don't do `while (!my_file.eof())`; 2) Null-terminate the "strings"; 3) Reset the `column` for each row; And 4) Check for the null-terminator when printing. – Some programmer dude Oct 29 '21 at 12:40

3 Answers3

0

Hmm, a 2D char array can indeed be used to store an number of lines, but you should control that you never try to store more than 50 characters for a single line, and that you never try to ouput more characters for a line than what it initially contained.

Here is a minimal fix of your code:

int rows = 0, column = 0;
char arr[50][50] = { {0 } };  // ensure the array is initialized with '\0' chars
for (;;) {
    my_file.get(ch);
    if (!my_file) break;   // eof shall be tested AFTER a read operation
    if (ch == '\n') {
        rows++;
        if (rows == 50) break;   // no more than 50 lines
        column = 0;              // reset column index for next line
    }
    else if (column < 50) {      // no more than 50 columns
        arr[rows][column] = ch;
        column++;
    }
}
for (int j = 0; j < rows; j++) {
    for (int k = 0; k < 50; k++) {
        if (arr[j][k] == 0) break;   // stop on end of line
        std::cout << arr[j][k];
    }
    std::cout << '\n';               // and display the end of line
}

And as you have been said this is rather C-ish... I assume it is only for learning how 2D arrays can work.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

As pointed out in comments, you'd be much better off using a std::vectorstd::string to store the strings.

But, this looks like a homework assignment to read then print each byte separately, so let's have a look... I'll add one of the ways this is usually done at the end of this post.

Your output looks like this:

enter image description here

It looks like you are displaying characters beyond the bondary of the strings, or that your strings are not null terminated... Turns out it's both.

Your code:

int rows = 0, column = 0;
char arr[50][50];            // <-- your array is not initialized, while that is not
                             // a big issue, filling the array with zeroes is easy:
                             //  char arr[50][50] = {};

while (my_file.eof() == 0) {
    my_file.get(ch);
    if (ch == '\n') {
        rows++;             // <-- you pass to the next string, but do not put a 
                            // null character to properly terminate your strings
                            // while this could have been avoided by initializing 
                            // the array, it's best to do it explicitely.

        // replace above line contents by:
        arr[row][column] = '\0';

        if (++row >= 50)     // consider using named constants for the size of your array.
            break;           // No use keeping on reading strings if there is no 
                             // more room to store them
    }

    arr[rows][column] = ch;   // <-- I suspect a bunch un undefined stuff will 
                            // start happening when column >= 50
    column++;

    // Try replacing above code with:
    if (column < 50)      // consider using named constants for the size of your array.
        arr[rows][column++] = ch;
}

// make sure the last string is null terminated.
if (row < 50 && column < 50)
   arr[row][column] = '\0';

// note that strings that are 50 bytes long are NOT null terminated.
// that's important to keep in mind, and only workss because we'll print
// byte by byte.

// your original print routine prints out all characters in the array, even 
// stuff that was not in the original file...
for (int j = 0; j < rows; ++j){
    for (int k=0 ; k < column; ++k){   // <-- you need to check for a null 
                                       // terminating character here...
                                       // also, column is the length of the last 
                                       // string in the array.  This is not a very 
                                       // useful value for displaying any other
                                       // strings, is it?

    // try this:
    for (int k = 0; k < 50 && arr[j][k] != '\0'; ++k)
        cout << arr[j][k];
    }
    cout << '\n';                      // insert a newline after each string.
}

As you can tell, this is overly complex for doing a very common operation... Here's a more concise way of doing the same thing:

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


int main()
{
    std::vector<std::string> arr;
    std::ifstream ifs("testfile.txt");

    while (ifs && !ifs.eof())
    {
        std::string str;
        std::getline(ifs, str);
        arr.push_back(str);
    }

    for (size_t i = 0; i < arr.size(); ++i)
        std::cout << arr[i] << '\n';

    return 0;
}
Michaël Roy
  • 6,338
  • 1
  • 15
  • 19
-1

Because you haven't compile the array yet

char arr[50][50];
for (int r = 0; r < 50; r++){
    for (int c = 0; c < 50; c++){
        arr[r][c] = ' ';}
}