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

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

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

magento2 - Magento 2 admin grid add filter to collection -