How to reverse order numbers in a text file then write the reversed numbers back into the text file

These are the errors I am running into I am doing a simple project but the main problem lies where I am trying to simply reverse the numbers of a text file for example 1234 and then rewrite to the text file to make it say 4321 I know my while loop is wrong, I was just trying a bunch of stuff to see if I can get it working but I had 0 luck getting anywhere, thank you for those of you who can help, it means a lot.

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

    int main()
  {
    //int myArray[36];
    int myCount = 0;

    //printf("Hello World \n");
    FILE* fp = fopen("Numbers.txt", "r");
    if (fp == NULL)
    {
    printf("Can't open file!\n");

    return 1;
    }

    while (myCount != 0)
    {
        {
            for(int i = myCount - 1; i >= 0; i --)
        }
    }

    FILE* fp = fopen("Numbers.txt", "w");

    fclose(fp);

    return 0;
}

the expected result is that I expect the output of 1234 to be 4321 and so on and so forth with like numbers where 123456789 would be 987654321 but I currently do not have an actual output as that is what I am trying to achieve/ get, I will let those know who answer my question to let them know that it is what I need.

1 answer

  • answered 2019-09-10 03:03 David C. Rankin

    Alright, to read a sequence of numbers and then write them back out in reverse order, you simply need to read the values into an array, keeping track of how many you read, close the file opened for reading, reopen the file for writing, then write the values back out to the file in reverse order.

    We will leave reading an unknown number of values from the file and dynamically allocating storage for another day. We will presume for now that you have less than 256 values to read (adjust as necessary). Avoid using magic-numbers in your code, so if you need a constant to size your array, #define one (or more),

    #include <stdio.h>
    
    #define MAXI 256    /* if you need a constant, #define one (or more) */
    

    Now declare your array, declare a counter, and since you also do not hardcode filenames, pass the filename to open as the first argument to your program (or read from stdin by default if no argument is given):

    int main (int argc, char **argv) {
    
        int arr[MAXI] = {0};    /* array for storing values */
        size_t n = 0;           /* counter for number stored */
        /* use filename provided as 1st argument (stdin by default) */
        FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
    
        if (!fp) {  /* validate file open for reading */
            perror ("file open failed");
            return 1;
        }
    

    Now since you have a fixed array, you cannot read more integer values that you have array elements to hold -- so always protect your array bounds when filling your array. With your file open for reading, all you need to do is read the integers from the file, and close the file after either filling all elements in your array, or reaching the end of file (EOF). Close the file you have open for reading when done:

        /* protect your array bounds, and read/validate 1 int per iteration */
        while (n < MAXI && fscanf (fp, "%d", &arr[n]) == 1)
            n++;    /* on success, increment counter */
    
        if (fp != stdin)   /* close file if not stdin */
            fclose (fp);
    

    To write the values in reverse order, simply open your file for writing (which will truncate your file). Here you can write to stdout by default if no filename was given. Then loop from your last array element (n - 1) to zero writing each element to your file in reverse order. Close the file when done, but always validate the close after writing to detect any stream errors that may occur that are not otherwise reported:

        /* open file for writing (stdout by default) */
        fp = argc > 1 ? fopen (argv[1], "w") : stdout;
    
        if (!fp) {  /* validate file open for writing */
            perror ("file open failed");
            return 1;
        }
    
        while (n--) /* write array in reverse order to file */
            fprintf (fp, "%d\n", arr[n]);
    
        if (fp != stdout)           /* close file if not stdout */
            if (fclose(fp) == -1)   /* always validate close-after-write */
                perror ("fclose-fp");
    }
    

    That's it. The full code above would be:

    #include <stdio.h>
    
    #define MAXI 256    /* if you need a constant, #define one (or more) */
    
    int main (int argc, char **argv) {
    
        int arr[MAXI] = {0};    /* array for storing values */
        size_t n = 0;           /* counter for number stored */
        /* use filename provided as 1st argument (stdin by default) */
        FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
    
        if (!fp) {  /* validate file open for reading */
            perror ("file open failed");
            return 1;
        }
    
        /* protect your array bounds, and read/validate 1 int per iteration */
        while (n < MAXI && fscanf (fp, "%d", &arr[n]) == 1)
            n++;    /* on success, increment counter */
    
        if (fp != stdin)   /* close file if not stdin */
            fclose (fp);
    
        /* open file for writing (stdout by default) */
        fp = argc > 1 ? fopen (argv[1], "w") : stdout;
    
        if (!fp) {  /* validate file open for writing */
            perror ("file open failed");
            return 1;
        }
    
        while (n--) /* write array in reverse order to file */
            fprintf (fp, "%d\n", arr[n]);
    
        if (fp != stdout)           /* close file if not stdout */
            if (fclose(fp) == -1)   /* always validate close-after-write */
                perror ("fclose-fp");
    }
    

    (note: since you didn't provide an example of your input file, a newline separated set of integers was assumed. Adjust the output format as needed)

    Example Input File

    $ cat dat/10intordered.txt
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    

    Example Use/Output

    Reading stdin wrting to stdout (just pass your filename as 1st argument to read/write to a file),

    $ ./bin/revfile < dat/10intordered.txt
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    

    Look things over and let me know if you have further questions.

    Edit Removing Shortcuts & Adding Program Progress Output

    With a few edits we can remove the size_t and the shortcut while(n--) loop to make things look more traditional using int and a for loop in reverse order for the second loop. We also added progress messages for both reading and writing. I used an actual file to the information is read and written back to a file to not clutter the program progress notes with the array being written in between:

    #include <stdio.h>
    
    #define MAXI 256    /* if you need a constant, #define one (or more) */
    
    int main (int argc, char **argv) {
    
        int arr[MAXI] = {0};    /* array for storing values */
        int n = 0;              /* counter for number stored */
        /* use filename provided as 1st argument (stdin by default) */
        FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
    
        if (!fp) {  /* validate file open for reading */
            perror ("file open failed");
            return 1;
        }
    
        puts ("reading file:");
        /* protect your array bounds, and read/validate 1 int per iteration */
        while (n < MAXI && fscanf (fp, "%d", &arr[n]) == 1) {
            printf ("  arr[%3d] : %d\n", n, arr[n]);
            n++;    /* on success, increment counter */
        }
        printf ("read of %d integers -- complete.\n", n);
    
        if (fp != stdin)   /* close file if not stdin */
            fclose (fp);
    
        /* open file for writing (stdout by default) */
        fp = argc > 1 ? fopen (argv[1], "w") : stdout;
    
        if (!fp) {  /* validate file open for writing */
            perror ("file open failed");
            return 1;
        }
    
        puts ("\nwriting values to file:");
        /* loop writing indexes out from n-1 to 0 */
        for (int i = n-1; i >= 0; i--) {
            printf ("  arr[%3d] : %d\n", i, arr[i]);
            fprintf (fp, "%d\n", arr[i]);
        }
        printf ("write of %d integers -- complete.\n", n);
    
        if (fp != stdout)           /* close file if not stdout */
            if (fclose(fp) == -1)   /* always validate close-after-write */
                perror ("fclose-fp");
    }
    

    Example Input File

    $ cat dat/10i.txt
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    

    Example Use/Output

    $./bin/revfile2 dat/10i.txt
    reading file:
      arr[  0] : 1
      arr[  1] : 2
      arr[  2] : 3
      arr[  3] : 4
      arr[  4] : 5
      arr[  5] : 6
      arr[  6] : 7
      arr[  7] : 8
      arr[  8] : 9
      arr[  9] : 10
    read of 10 integers -- complete.
    
    writing values to file:
      arr[  9] : 10
      arr[  8] : 9
      arr[  7] : 8
      arr[  6] : 7
      arr[  5] : 6
      arr[  4] : 5
      arr[  3] : 4
      arr[  2] : 3
      arr[  1] : 2
      arr[  0] : 1
    write of 10 integers -- complete.
    

    Updated File

    $ cat dat/10i.txt
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    

    See if that may not help a bit more and let me know if you are still confused on any areas.