Home > front end >  Not able to print this 2D array (weird output) in C
Not able to print this 2D array (weird output) in C

Time:04-11

I am trying to read a text file with 100 numbers like 1 2 45 55 100 Weird Output of array

Here is my code:

#include <stdio.h>

#define NR 10
#define NC 10

int main(void) {
    int numbers[9][9];
    int i = 0;
    int count;
    int j = 0;
    FILE *file;

    file = fopen("numbers.txt", "r");
    for (count = 1; count < 101; count  ) {   
        fscanf(file, "%d", &numbers[i][j]);
        j  ;
        if ((count != 1) && (count % 10 == 0)) {
            i  ;
            j = 0;
        }
    }
      
    fclose(file);
    
    int p = 0;
    int q = 0;
    for (p = 0; p < NR; p  ) {
        for (q = 0; q < NC; q  ) {
            printf("%d", numbers[p][q]);
        }
        printf("\n");
    }
    return 0;
}

CodePudding user response:

As SparKot noted in a comment, to read a 10x10 matrix, you need to define the matrix with 10x10 elements:

int numbers[10][10];

That has to be one of the weirder ways of reading a 10x10 matrix that I've ever seen. Why not go for a simple approach of nested loops. Since the data contains floating-point numbers, you need to read them as double (or perhaps float) values.

for (int i = 0; i < 10; i  )
{
    for (int j = 0; j < 10; j  )
    {
        double double_val;
        if (fscanf(file, "%lf", &double_val) != 1)
        {
            fprintf(stderr, "failed to read matrix[i][j]\n", i, j);
            exit(EXIT_FAILURE);
        }
        numbers[i][j] = double_val;
    }
}

The mess with double_val works around the data containing floating point numbers and your original code trying to read integers. You'll get one valid value; thereafter, fscanf() will return 0 because the . is not a part of a valid integer. This highlights the importance of checking the return value from fscanf() and its relatives.

Frankly, you should be using double numbers[10][10]; for the data from the file. Then you could read directly into the array:

if (fscanf("%lf", &numbers[i][j]) != 1)

But you'd need to check (and probably change) all the rest of the code too.

CodePudding user response:

There are multiple issues in your code:

  • the matrix is too small, make it numbers[NR][NC].
  • you do not check for fopen failure: you will have undefined behavior if the file numbers.txt is not in the current directory or cannot be open for reading.
  • you read the file contents as integers, but the file contains floating point numbers with a . decimal separator: the second and subsequent fscanf() will get stuck on the . and keep returning 0 without modifying the destination number, leaving the matrix mostly uninitialized. Make the matrix double numbers[NR][NC], read the numbers with %lf and test for conversion failure.
  • the counting method in the reading loop is weird. Just use 2 nested for loops with proper counter and tests.
  • printing the matrix contents, you should output at least a space between numbers so the output is readable.

Here is a modified version:

#include <errno.h>
#include <stdio.h>
#include <string.h>

#define NR 10
#define NC 10

int main() {
    double numbers[NR][NC];
    FILE *file;

    file = fopen("numbers.txt", "r");
    if (file == NULL) {
        fprintf(stderr, "cannot open numbers.txt: %s\n", strerror(errno));
        return 1;
    }
    for (int i = 0; i < NR; i  ) {   
        for (int j = 0; j < NC; j  ) {   
            if (fscanf(file, "%lf", &numbers[i][j]) != 1) {
                fprintf(stderr, "error reading number at row %d, col %d\n",
                        i   1, j   1);
                fclose(file);
                return 1;
            }
        }
    }
    fclose(file);
    
    for (int p = 0; p < NR; p  ) {
        for (int q = 0; q < NC; q  ) {
            printf(" %5g", numbers[p][q]);
        }
        printf("\n");
    }
    return 0;
}

CodePudding user response:

Clear all a common condition that causes programs to crash; they are often associated with a file named core. code is showing segmentation fault.

  • Related