0

I am currently trying to work on a program that will read in a file line by line and place the content in an array. Then trying to reverse the original array into a second array so I can later compare the two arrays. My current code is

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

     void reversing(char buffer[], char reverse[], int stringLength);

     int main(int argc, char const *argv[])
     {
        int stringLength = 0;
        FILE *fp;   //Declaring a FILE type pointer calling it fp
        char buffer[64]; //Declaring a char array the size of 64 named buffer

        fp = fopen("./test.txt", "r"); 
        if(fp == NULL)
        {
          printf("File did not open!\n");
        }
        else
        {
              while(fgets(buffer, 64, (FILE*)fp) != NULL)
              {
                 printf("\nNormal String: %s", buffer); //Print content in buffer(original array)
                 stringLength = strlen(buffer);        //Storing the length of the readed input

                 char reverse[stringLength];  //Creating array for reversed comparision(comparision not implemented yet)

                 printf("String length: %d\n", stringLength); //Print string length(for debugging)
                 reversing(buffer, reverse, stringLength);
                 printf("Reversed String: %s\n", reverse);//Print content in reverse(Reverse array)
             }

             printf("\n\nEND OF FILE Reached!\n");

             fclose(fp);
       }    
        return 0;
    }

    void reversing(char buffer[], char reverse[], int stringLength)
    {
       int i = 0;
       int j = stringLength - 1;

       while(i < j)
       {
       reverse[j] = buffer[i];
       i++;
       j--;
       }
    }

My test file is simply

    A
    AB
    ABC
    ABCD
    ABCDE

It should print to the screen

   Normal String:   A
   Reversed String: A 
   Normal String:   AB 
   Reversed String: BA
   Normal String:   ABC 
   Reversed String: CBA
   Normal String:   ABCD 
   Reversed String: DCBA
   Normal String:   ABCDE 
   Reversed String: EDCBA

When I run the program through a debugger it shows that once inside the reversing function the letters are being swap correctly; however, once it exits the function and the call to print the reversed array is made it is printing garbage, but inside the garbage are the first two elements swap correctly. Any help of suggestion would be greatly appreciated.

As a side note I am trying to make this as simple as possible since the true objective or this program is to take it and implement it in assembly on a ci20 machine.

TurtleMan
  • 175
  • 2
  • 15
  • There are two things that you forget: The first is that [`fgets`](http://en.cppreference.com/w/c/io/fgets) adds the newline at the end. The second thing is that strings in C is a sequence of characters ended *with a terminator*. So a string of length four (like `"ABCD"`) is actually *five* characters including the terminator. You forget this last thing, about the terminator, *twice*. – Some programmer dude Nov 02 '16 at 08:22
  • There are some other problems in your `reverse` function too. Use a debugger to step through the code line by line to find out what and why. – Some programmer dude Nov 02 '16 at 08:28

4 Answers4

2
stringLength = strlen(buffer); //Storing the length of the readed input

char reverse[stringLength];   //Creating array for reversed comparision(comparision not implemented yet)

You don't have enough space to store the trailing \0

char reverse[stringLength]; 

should be

char reverse[stringLength + 1]; 

And don't forget to add this traling \0 at the very end in your reverse function:

reverse[stringLength] = '\0';

But notice that (in this case) you don't need a temporary to reverse the string, just pass the original one and swap until the NUL character is reached, take a look to How do you reverse a string in place in C or C++?

Community
  • 1
  • 1
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
0

If you are looking for a really simple solution, you can use strrev from the string.h library. It reverses the string for you, which means you don't have to make your own string reversing function. You can just call it instead.

Something like this:

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

#define BUFFSIZE 64

int
main(void) {
    FILE *filename;
    char buffer[BUFFSIZE];
    int length;

    filename = fopen("test.txt", "r");

    if (filename == NULL) {
        fprintf(stderr, "%s\n", "Error Reading File!");
        exit(EXIT_FAILURE);
    }

    while (fgets(buffer, BUFFSIZE, filename) != NULL) {
        length = strlen(buffer)-1;

        if (buffer[length] == '\n') {
            buffer[length] = '\0';
        }

        printf("Normal String: %s\n", buffer);
        printf("Reversed String: %s\n", strrev(buffer));
    }
    return 0;
}
RoadRunner
  • 25,803
  • 6
  • 42
  • 75
0

Your problem lies in the line while (i < j) in your reversing function. i will end up being less than j when only half of your array will be reversed. Instead, it should be while (i < stringLength)

You should also change your character array char reverse[stringLength] to char reverse[stringLength + 1] so you have space for the '\0' terminating character, which you should add to the array at the end of your reversing function.

It should look like this:

void reversing(char buffer[], char reverse[], int stringLength)
{
    int i = 0;
    int j = stringLength - 1;

    while(i < stringLength)
    {
        reverse[j] = buffer[i];
        i++;
        j--;
    }
    reverse[i] = '\0';
}

Also note that the read function for the file is also reading in a newline character and the reversing function is placing it at the beginning of your reversed string, so output looks like this:

Normal String: A
String length: 2
Reversed String: 
A

Normal String: AB
String length: 3
Reversed String: 
BA

Normal String: ABC
String length: 4
Reversed String: 
CBA

Normal String: ABCD
String length: 5
Reversed String: 
DCBA

Normal String: ABCDE
String length: 6
Reversed String: 
EDCBA


END OF FILE Reached!

I'll leave it up to you to figure out removing the newline character before sending it to the reversing function. If you can't figure it out, just comment it under this answer and I'll edit the answer.

PhantomWhiskers
  • 218
  • 1
  • 10
  • Thank you for your response. Soon as I started reading the answers and seen that I was forgetting about the `'\0'`. I did a face to palm jester. As for dealing with the `fgets` carrying the `'\n'` I just shifted the contents of the array over by one. Adding this code to my `reversing function`. `i = 0 while(i < stringLength) { reverse[i] = reverse[ i +1]; i++; }` – TurtleMan Nov 02 '16 at 17:47
0

In order to solve my problems reversing the array and forgetting about the '\0', not allowing enough space for the '\0', and dealing with fgets adding a newline. Here is my current code that runs correctly.

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

    void reversing(char buffer[], char reverse[], int stringLength);

    int main(int argc, char const *argv[])
    {
      int stringLength = 0;
      FILE *fp;         //Declaring a FILE type pointer calling it fp
      char buffer[64];  //Declaring a char array the size of 64 named buffer
      fp = fopen("./test.txt", "r");

      if (fp == NULL)
      {
        printf("File did not open\n");
        return 0;
      }
      else
      {
        while(fgets(buffer, 64, (FILE*)fp) != NULL)
        {
          printf("\nNormal String:   %s", buffer); //Print content in buffer(original array)
          stringLength = strlen(buffer);           //Storing the length of read input

          char reverse[stringLength + 1];

          reversing(buffer, reverse, stringLength);
          printf("Reversed String: %s\n", reverse);//Print content in reverse(Reverse array)
        }

      printf("\nEND OF FILE Reached!\n");
     }
     fclose(fp);
     return 0;
   }

  void reversing(char buffer[], char reverse[], int stringLength)
  {
    int i = 0;
    int j = stringLength - 1;
    while(i < stringLength)
    {
      reverse[j] = buffer[i]; //Swap elements
      i++;
      j--;
    }
    reverse[i] = '\0'; //Add null terminating 

    i = 0;
    if(reverse[0] == '\n') //If first element is '\n' swift elements
    {
       while(i < stringLength)
       {
        reverse[i] = reverse[i + 1];
        i++;
       }
    }
  }

It now prints to the screen

    Normal String:   A
    Reversed String: A

    Normal String:   AB
    Reversed String: BA

    Normal String:   ABC
    Reversed String: CBA

    Normal String:   ABCD
    Reversed String: DCBA

    Normal String:   ABCDE
    Reversed String: EDCBA

    END OF FILE Reached!

Thank you @PhantomWhiskers and everyone that commented and provided possible solutions to my original question.

TurtleMan
  • 175
  • 2
  • 15