-1

When I use fprintf, it actually saves the wrong content.

Usually fprintf outputs what I want, but this time it's outputting seemingly irrelevant numbers, and I don't know what the problem is.

My Inputs & Expected output

1 2 3
4 5 6
7 8 9

Actual Output

3 0 4199352 
1 11 0 
9 0 2 

I used a for loop to output a two-dimensional array

My code

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

void filein(int x, int y) {
    FILE *fin;
    int s[x][y];
    int i, j;
 
    if ((fin = fopen("test.txt", "r")) == NULL) {
        printf(" can't open");
    }
    else {
        printf("opening...\n");
    }

    for (i = 0; i < x; i++) {
        for (j = 0; j < y; j++) {
            fscanf(fin, "%d", &s[i][j]);
        }
  
        fscanf(fin, "\n");
    }
  
    fclose(fin);
  
    for (i = 0; i < x; i++) {
        for (j = 0; j < y; j++) {
            printf("%d ", s[i][j]);
            fflush(stdout);//输出
        }
      
        printf("\n");
    }
}

void fileout(int x, int y) {
    FILE *fout;
    int s[x][y];
    int i, j;
    char outname[50];
    printf("please input the name of output file (no include\".txt\"):\n");
    fflush(stdout);
    scanf("%s", outname);
    strcat(outname, ".txt\0");
    fout = fopen(outname,"w");
    
    if (fout == NULL) {
        printf("Error!");
        fflush(stdout);
    }
    else {
        printf("Writing....\n");
        fflush(stdout);
    }
    
    for (i = 0; i < x; i++) {
        for (j = 0; j < y; j++) {
            fprintf(fout, "%d ", s[i][j]);
        }

        fprintf(fout,"\n");
    }
    
    fclose(fout);
}

int main() {
    int x, y;
    printf("what is m?\n");
    fflush(stdout);
    scanf("%d", &x);
    printf("what is n?\n");
    fflush(stdout);
    scanf("%d", &y);
    filein(x, y);
    fileout(x, y);
    printf("finish");
    fflush(stdout);

    return 0;
}
Steve Friedl
  • 3,929
  • 1
  • 23
  • 30
Zero
  • 21
  • 3
  • Have you tried running your code line by line in a debugger while monitoring the values of all variables, in order to determine at which point your program stops behaving as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – Andreas Wenzel Mar 04 '22 at 03:08
  • 6
    `s` is a local uninitialized variable in the `fileout` function. It is not connected with the variable `s` in the `filein` function which is another local variable. You should declare the variable in `main` and pass it as a parameter to the functions. – Retired Ninja Mar 04 '22 at 03:08
  • Note that you have no idea whether any of the `fscanf()` calls succeeded. When you start getting erroneous behaviour, you have to add the error checking that should have been there in the first place. – Jonathan Leffler Mar 04 '22 at 03:21
  • While it isn't so much of problem when reading from a file, in general, [trailing white space in a format string is not a good idea](https://stackoverflow.com/questions/19499060/what-is-the-effect-of-trailing-white-space-in-a-scanf-format-string) — so `fscanf(fin, "\n");` is problematic. It's also unnecessary — most scan conversions skip white space automatically. There are three that don't: `%c`, `%[…]` (scan sets), and `%n`. Note that any white space character (blank, tab, newline, etc) in the `scanf()` format string skips zero or more white space characters. Newlines are not material. – Jonathan Leffler Mar 04 '22 at 03:40

2 Answers2

0

The problem is that your fileout function doesn't have access to the data you read in your filein function. You read it into an array on the stack (the local variable s[x][y]), and then returned - that information is now gone. Then when fileout runs, the new s[x][y] is at some other place on the stack and you are just printing out whatever happens to be in memory there.

That's why your debugging printouts in filein show that you've read the data correctly, but the output is garbage.

You'll need to malloc your space for the numbers in main and pass it around, or call a helper function between main and filein and fileout that allocates s on the stack as you've already done (but only once) and then passes s into the other functions.

Alex Nicolaou
  • 217
  • 1
  • 4
0

Your 2d array s in fileout function is allocated garbage numbers in the memory that's why you are getting different numbers from the numbers inside test.txt.

so I have solved that for you by defining a struct int_array2d_t* that has x and y of type size_t and array variables that could be accessed whenever needed.

The code that I added has comments that explain it, however, let me know if you do not understand sth!

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

/* define a struct that has x, y of type size_t and array */
typedef struct
{
  size_t x;
  size_t y;
  int array [];
} int_array2d_t;


/* initialize pointer of type struct int_array2d_t */
int_array2d_t* array2d = NULL;

void filein(int x, int y) {
    FILE *fin;
    int s[x][y];
    int i, j;
 
    if ((fin = fopen("test.txt", "r")) == NULL) {
        printf(" can't open");
    }
    else {
        printf("opening...\n");
    }

    for (i = 0; i < x; i++) {
        for (j = 0; j < y; j++) {
            fscanf(fin, "%d", &s[i][j]);
        }
  
        fscanf(fin, "\n");
    }
  
    fclose(fin);

    double count = 0.0;
    for (i = 0; i < x; i++) {
        for (j = 0; j < y; j++) {
            /* copy each value in s to array2d */
            array2d->array[i*y + j] = s[i][j];
            printf("%d ", array2d->array[i*y + j]);
            fflush(stdout);//输出
        }
      
        printf("\n");
    }
}

void fileout(int x, int y) {
    FILE *fout;
 
    int i, j;
    char outname[50];
    printf("please input the name of output file (no include\".txt\"):\n");
    fflush(stdout);
    scanf("%s", outname);
    strcat(outname, ".txt\0");
    fout = fopen(outname,"w");
    
    if (fout == NULL) {
        printf("Error!");
        fflush(stdout);
    }
    else {
        printf("Writing....\n");
        fflush(stdout);
    }
    
    for (i = 0; i < x; i++) {
        for (j = 0; j < y; j++) {
            /* write value in array2d->array to the file stream */
            fprintf(fout, "%d ", array2d->array[i*y + j]);
        }

        fprintf(fout,"\n");
    }
    
    fclose(fout);
}

int main() {
    int x, y;
    printf("what is m?\n");
    fflush(stdout);
    scanf("%d", &x);
    printf("what is n?\n");
    fflush(stdout);
    scanf("%d", &y);

    /* allocate array2d with the new size after we get x and y */
    array2d = malloc(sizeof(*array2d) + sizeof(double[x][y]));
    array2d->x = x;
    array2d->y = y;

    filein(x, y);
    fileout(x, y);
    printf("finish");
    fflush(stdout);

    return 0;
}