Thread: Reversing file input

  1. #1
    Registered User
    Join Date
    Sep 2018
    Posts
    15

    Reversing file input

    I can get the code to flip every string/word. But i need to stop strings when they include special characters.
    INPUT: Homework 1 is due on Friday. Good$$?Luck!
    OUTPUT: krowemoH 1 si eud no .yadirF !kcuL?$$dooG
    The output should be krowemoH 1 si eud no yadirF. dooG$$?kcuL!.

    Code:
    #include <stdio.h>
    #include <string.h>
    //#include<stdlib.h>
    
    void reverse_string(char*);
    void reverse_words(char*);
    
    int main()
    {
    
    FILE *fp;
    char Input[255];
    fp = fopen("test.txt", "r");
    fgets(Input, 255, (FILE*)fp);
    printf("%s\n", Input);
    reverse_words(Input);
    printf("\n%s", Input);
    
      return 0;
    }
    
    void reverse_words(char *s) {
      char b[100], *t, *z;
      int c = 0;
    
      t = s;
    
      while(*t) {                           //processing complete string
        while(*t != ' ' && *t != '\0') {    //extracting word from string
          b[c] = *t;
          t++;
          c++;
        }
        b[c] = '\0';
        c = 0;
    
        reverse_string(b);        // reverse the extracted word
    
        z = b;
    
        while (*z) {    //copying the reversed word into original string
          *s = *z;
          z++;
          s++;
        }
    
        if (*s == ' ') //Skipping spaces
            {
                s++;
            }
        t = s;                              // pointing to next word
      }
    
    
    }
    
    
    void reverse_string(char *t) {
      int l, c;
      char *e, s, *z;
      l = strlen(t);
      e = t + l - 1;
      z = t + l - 2;
    
      for (c = 0; c < l/2; c++) {
        s  = *t;
        *t = *e;
        *e = s;
        t++;
        e--;
        }
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    This is not a good idea:
    Code:
    void reverse_words(char *s) {
      char b[100], *t, *z;
      int c = 0;
    What I mean is that you declared five variables, all of which having single character names. Such variable names are common for loop and array indices, perhaps for variables in a very small scope such that their purpose and meaning is blatantly obvious, and sometimes for certain domain-specific purposes, but otherwise they tend to be poorly chosen because they are not descriptive.

    Since you seem to be willing to work with pointers, I suggest an entirely in-place version of what you are trying to do, inspired by the loop structure that you outlined:
    Code:
    void reverse_words(char *text) {
        char *word_start = text;
        char *word_end;
        while (*word_start != '\0') {
            /* use a loop to increment word_start until it points to a character
               that is a '\0', or is neither whitespace nor a special character
               ... */
    
            word_end = word_start;
            /* use a loop to increment word_end until it points to a character that
               is a '\0', whitespace, or a special character
               ... */
    
            reverse_word(word_start, word_end);
            word_start = word_end;
        }
    }
    
    void reverse_word(char *word_start, char *word_end) {
        /* reverse the word using the start and end pointers, keeping in mind that
           word_end points to the character immediately after the word's last
           non-special character, so you should not alter what it points to;
           one way to do this is to first decrement word_end, then loop to
           increment word_start and decrement word_end until word_start is no
           longer less than word_end, swapping characters as you go
           ... */
    }
    Last edited by laserlight; 09-21-2018 at 05:39 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User Kernelpanic's Avatar
    Join Date
    Sep 2018
    Location
    Berlin
    Posts
    105
    Reverse a string is a shortly programm only. For Your special whishes You have to a little bit experiment.
    Compiled with GCC for Windows.

    Code:
    //Reverse a string, 24. Sept. 2018
    
    #include<stdio.h>
    #include<string.h>
     
    int main(void)
    {
       char zeichenkette[100];
      
      printf("Give me a string: ");
      gets(zeichenkette);
        
       printf("Zeichenkette orginal: %s\n\n",zeichenkette); 
      
      // -strrev- reverse a string
      //-strdup- calls malloc() for check of space
       printf("Zeichenkette after rerverse: %s",strrev(strdup(zeichenkette)));
     
       return 0;
    }
    Reversing file input-reverseastring-jpg

  4. #4
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,127
    Quote Originally Posted by Kernelpanic View Post
    Reverse a string is a shortly programm only. For Your special whishes You have to a little bit experiment.
    Compiled with GCC for Windows.

    Code:
    //Reverse a string, 24. Sept. 2018
    
    #include<stdio.h>
    #include<string.h>
     
    int main(void)
    {
       char zeichenkette[100];
      
      printf("Give me a string: ");
      gets(zeichenkette);
        
       printf("Zeichenkette orginal: %s\n\n",zeichenkette); 
      
      // -strrev- reverse a string
      //-strdup- calls malloc() for check of space
       printf("Zeichenkette after rerverse: %s",strrev(strdup(zeichenkette)));
     
       return 0;
    }
    strrev() is not a Standard Library function. It is not available on Linux.

    gets() is depreciated under C99, and has been removed as of C11. Please use fgets() instead!

    If you use strdup(), you should free() the pointer returned from the function, even if it is near the end of the program.

  5. #5
    Registered User Kernelpanic's Avatar
    Join Date
    Sep 2018
    Location
    Berlin
    Posts
    105
    Yes, gets() is outdated says MS. But the newest GCC (mingw) compiled it without mistake message. It use maybe the MS Library. - fgets() coming later.

    Code:
    //Reverse a string, 24. Sept. 2018
    //For Window-Systems only - strrev, strdup
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int main(void)
    {
       char zeichenkette[100];
       char *zgr = zeichenkette;
         
       printf("Give me a string: ");
       gets(zeichenkette);
              
       printf("\n");
       printf("Zeichenkette original: %s\n\n",zgr); 
         
       // -strrev- reverse a string
       //-strdup- calls malloc() for check of space
       printf("Zeichenkette after reverse: %s",strrev(strdup(zgr)));
       free(zgr);
     
       return 0;
    Reversing file input-reverse-zkget-jpg
    Last edited by Kernelpanic; 09-25-2018 at 08:53 AM.

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Yes, gets() is outdated says MS. But the newest GCC (mingw) compiled it without mistake message.
    Then you're compiler is probably not properly set up.

    Here is what my compiler says about your program:

    ||=== Build: Debug in chomework (compiler: GCC 8-1) ===|
    main.c||In function ‘main’:|
    main.c|16|error: implicit declaration of function ‘gets’; did you mean ‘fgets’? [-Wimplicit-function-declaration]|
    main.c|23|error: implicit declaration of function ‘strrev’; did you mean ‘strlen’? [-Wimplicit-function-declaration]|
    main.c|23|error: implicit declaration of function ‘strdup’; did you mean ‘strcmp’? [-Wimplicit-function-declaration]|
    main.c|23|warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]|
    ||=== Build failed: 3 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|

    Using the current C standard the gets() function is no longer depreciated, it has actually been removed from the standard. The strrev() and strdup() functions are not standard C functions not available on my system.

  7. #7
    Registered User Kernelpanic's Avatar
    Join Date
    Sep 2018
    Location
    Berlin
    Posts
    105
    So, now it's enough! Last post was too early!
    Compiled like before - no mistakes.

    Code:
    //Reverse a string, 25. Sept. 2018
    //Benutzt fgets()
    //For Window-Systems only - strrev, strdup
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    #define MAX 100
    
    
    int main(void)
    {
       char zeichenkette[MAX];
       char *zgr = zeichenkette;
         
       printf("Give me a string: ");
       fgets(zeichenkette, MAX, stdin);
              
       printf("\n");
       printf("Zeichenkette original: %s\n\n",zgr); 
         
         // -strrev- reverse a string
        //-strdup- calls malloc() for check of space
       printf("Zeichenkette after reverse: %s",strrev(strdup(zgr)));
       free(zgr);
     
       return 0;
    }

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Where did you manually allocate (with malloc/calloc) the memory that you're freeing on line 28?

    Why do you even need that pointer?

  9. #9
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,127
    strdup() duplicates the string passed by malloc'ing the data space, that free() needs to be called to free up the memory.

    Actually, "zgr" is not the pointer that should be freed!!!

    The pointer returned from strdup() should be captured to a pointer, then THAT pointer should be freed after!!! That address is being used by printf() but then thrown away!!! I didn't catch that! ;^)
    Last edited by rstanley; 09-25-2018 at 11:31 AM.

  10. #10
    Registered User Kernelpanic's Avatar
    Join Date
    Sep 2018
    Location
    Berlin
    Posts
    105
    Quote Originally Posted by jimblumberg View Post
    Where did you manually allocate (with malloc/calloc) the memory that you're freeing on line 28?

    Why do you even need that pointer?
    This is because strdup () calls malloc () to check if there is enough space for the operation. And this area should given free after operation.


    With the pointer the program is working - no mistake messages from the gcc.

  11. #11
    Registered User Kernelpanic's Avatar
    Join Date
    Sep 2018
    Location
    Berlin
    Posts
    105
    Quote Originally Posted by rstanley View Post
    strdup() duplicates the string passed by malloc'ing the data space, that free() needs to be called to free up the memory.

    Actually, "zgr" is not the pointer that should be freed!!!

    The pointer returned from strdup() should be captured to a pointer, then THAT pointer should be freed after!!! That address is being used by printf() but then thrown away!!! I didn't catch that! ;^)
    Now it gets complicated! I will see it tomorrow ...

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Kernelpanic
    Now it gets complicated! I will see it tomorrow ...
    I suggest that you start your own thread. Although Passwaters has not replied in more than 3 days, you're still derailing Passwaters' post with your own as your solution has nothing to do with Passwaters' problem other than the word "reverse": you're reversing entire strings, whereas Passwaters wants to effectively tokenise a string (read from file) to reverse "word" by "word" with consideration for certain special characters.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reversing The Linked List by reversing the links only
    By bitanbasak in forum C Programming
    Replies: 7
    Last Post: 08-25-2016, 09:24 AM
  2. Replies: 4
    Last Post: 09-01-2014, 08:14 AM
  3. Replies: 2
    Last Post: 08-30-2014, 11:07 PM
  4. Replies: 2
    Last Post: 03-05-2012, 10:35 AM
  5. Reversing word in a file
    By code_lover in forum C Programming
    Replies: 12
    Last Post: 09-23-2011, 10:26 PM

Tags for this Thread