c - How can I reverse the letters in each word of a string -


how can reverse words of string characters , numbers. example:

this start!  siht si eht trats! 

i've written code reverses (also '!'); output is:

siht si eht !trats 

code:

#include<stdio.h> void reverse(char *begin, char *end);     void reversewords(char *s)         {      char *word_begin = s;     char *temp = s;     while(isalnum(*temp) || *temp )          {               temp++;       if (*temp == '\0')             {                   reverse(word_begin, temp-1);             }             else if(*temp == ' ')             {             reverse(word_begin, temp-1);             word_begin = temp+1;         }   } }     void reverse(char *begin, char *end) {      char temp;     while (begin < end)     {         temp = *begin;         *begin++ = *end;         *end-- = temp;     }  }     int main() {      char s[50];     scanf("%[^\n]",&s);      char *temp = s;     reversewords(s);     printf("%s", s);      getchar();      return 0; } 

the reverse() function have useful tool need. many traditional versions rely on passing start of text reversed, purposes, passing pointers first , last characters of range reversed neat. use unchanged except trivia. make static because make every function (except main()) static unless there's header declares , used more 1 source file — there's 1 source file code.

all have identify start , end of each word in text. best done nested loops — 1 on 'not reached end of input string', , within that, skip on non-alphabetic (non-word) characters, record start of word, skip on alphabetic (word) characters, reverse word between start , end, , repeat outer loop.

that leads code this.

#include <ctype.h> #include <stdio.h> #include <string.h>  static void reverse(char *begin, char *end) {     while (begin < end)     {         char temp = *begin;         *begin++ = *end;         *end-- = temp;     } }  static void reversewords(char *s) {     while (*s != '\0')     {         while (*s != '\0' && !isalnum((unsigned char)*s))             s++;         char *word = s;         while (isalnum((unsigned char)*s))             s++;         reverse(word, s-1);     } }  int main(void) {     char s[1024];     while (fgets(s, sizeof(s), stdin) != 0)     {         s[strcspn(s, "\n")] = '\0';         printf("in:  [%s]\n", s);         reversewords(s);         printf("out: [%s]\n", s);     }      return 0; } 

the (unsigned char) cast necessary correctly handle accented characters in single-byte code set such iso 8859-15 on machine plain char signed type.

sample output:

this start! in:  [this start!] out: [siht si eht trats!] , isn't end. in:  [and isn't end.] out: [dna siht nsi't eht dne.]    neither leading blanks nor trailing ones interfere    in:  [   neither leading blanks nor trailing ones interfere   ] out: [   rehtien gnidael sknalb ron gniliart seno erefretni   ]  lots..of=intermediate=punctuation@interruptions.com^give&no&&&trouble   in:  [ lots..of=intermediate=punctuation@interruptions.com^give&no&&&trouble  ] out: [ stol..fo=etaidemretni=noitautcnup@snoitpurretni.moc^evig&on&&&elbuort  ] 

note if decide apostrophes should counted part of word (so "doesn't" maps "t'nseod" rather "nseod't" in code above), need fix condition in loops. @ point, i'd create static inline function job:

static inline int is_word_char(int c) {      return isalpha(c) || c == '\''; } 

note <ctype.h> reserves words starting is (and to) followed lower-case letter; using name is_word_char() avoids such reserved words. also, function defined take int, functions in <ctype.h>, simple consistency.

the reverse words function becomes:

static void reversewords(char *s) {     while (*s != '\0')     {         while (*s != '\0' && !is_word_char((unsigned char)*s))             s++;         char *word = s;         while (is_word_char((unsigned char)*s))             s++;         reverse(word, s-1);     } } 

it possible generalize reversewords() passing suitable pointer-to-function:

static void reversewords(char *s, int (*is_word)(int)) {     while (*s != '\0')     {         while (*s != '\0' && !is_word((unsigned char)*s))             s++;         char *word = s;         while (is_word((unsigned char)*s))             s++;         reverse(word, s-1);     } } 

now you'd remove inline is_word_char() because need actual function function pointer, , can use:

reversewords(s, isalnum); reversewords(s, is_word_char); 

the downside of degree of generalization cost of actual function call classify each character, losing possibilities of inlining classifier function.


sidelight on debugging

i typed preliminary version of answer reversewords() function looking this:

static void reversewords(char *s) {     while (*s != '\0')     {         while (!isalnum((unsigned char)*s))             s++;         char *word = s;         while (isalnum((unsigned char)*s))             s++;         reverse(word, s-1);     } } 

the difference in !isalnum loop — there isn't check null byte there. realized code must skipping past null byte(s). instrumenting this:

static void reversewords(char *s) {     while (*s != '\0')     {         while (/**s != '\0' &&*/ !isalnum((unsigned char)*s))         {             printf("= %d", *s);             s++;         }         putchar('\n');         char *word = s;         while (isalnum((unsigned char)*s))             s++;         reverse(word, s-1);     } } 

and running on "this start!" produced far output:

this start! in:  [this start!]  = 32 = 32 = 32 = 33= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0= -49= 0= -24 = -48= 41= 96 = -122= 46 = -1= 127= 0= 0= -120= -124= 46 = -1= 127= 0= 0 …many lines omitted… = -1= 127= 0= 0= -118= -113= 46 = -1= 127= 0= 0= -65= -113= 46 = -1= 127= 0= 0= 0= 0= 0= 0= 0= 0= 0= 0 = 95 = 61= 46= 47 out: [siht si eht trats!] 

the output appeared sane — code poking around sorts of places shouldn't have been.

the revised code safe long null byte fails "is word character" test.


Comments

Popular posts from this blog

magento2 - Magento 2 admin grid add filter to collection -

Android volley - avoid multiple requests of the same kind to the server? -

Combining PHP Registration and Login into one class with multiple functions in one PHP file -