how to perform reversing a sentence Word by Word in C?

非 Y 不嫁゛ 提交于 2019-12-02 07:14:12

Perhaps this belongs on the code review site instead?

Your approach seems very efficient to me (except that I would only call strlen(words) once and save the result in a register).

Two possible bugs look like:

wordend = strlen(words);

should be

wordend = strlen(words)-1;

and

for(j = wordstart ; j <= (wordend - wordstart) / 2 ; ++j) {

should be

for(j = wordstart ; j <= (wordend + wordstart) / 2 ; ++j) {

Final code looks like (with some extra {}):

    #include <stdio.h>
    int main(int argc,char *argv[])
    {
        int i,j;
        char words[]= "this is a test";
        int L=strlen(words);

        // Reverse each word
        for(i = 0; i < L; ++i) {
          int wordstart = -1;
          int wordend = -1;
          if(words[i] != ' ') 
          {
            wordstart = i;

            for(j = wordstart; j < L; ++j) {
              if(words[j] == ' ') {
                wordend = j - 1;
                break;
              }
            }
            if(wordend == -1)
              wordend = L-1;
            for(j = wordstart ; j <= (wordend + wordstart) / 2 ; ++j) {
              char temp = words[j];
              words[j] = words[wordend - (j - wordstart)];
              words[wordend - (j - wordstart)] = temp;
            }
            i = wordend;
          }
        }
        printf("reversed string is %s:",words);
        return 0;   
    }

You can create a double linked list as a base data structure. Then, iterate through the words and insert them in the list as you find them.

When you reach the end of the sentence, simply traverse the list backwards and print the words as you go through them

Sriram Jayaraman

Simply we can just use a n*1 2D character array tailored to suit our needs!!!

#include <stdlib.h>

int main()
{
    char s[20][20];
    int i=0, length=-1;
    for(i=0;;i++)
    {
        scanf("%s",s[i]);
        length++;
        if(getchar()=='\n')
            break;
    }
    for(i=length;i>=0;i--)
        printf("%s ",s[i]);
    return 0;
}

Start tokenizing the line from the last character and continue to the first character. Keep one pointer anchored at the base of the current word, and another pointed which will decrease while a word start is not found. When you find a word start while scanning like this, print from the word start pointer to the word end anchor. Update the word end anchor to the previous character of the current word start char.

You might want to skip the blankspace characters while scanning.

UPDATE

This is a quick implementation:

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

#define MAX_BUF 256

void show_string (char *str, int i, int n)
{
  while (i <= n)
  {
    printf ("%c", str[i]);
    i++;
  }
}

int main (void)
{
  char str[MAX_BUF];
  int end_anchor, start_ptr;
  int state;

  printf ("\nEnter a string: ");
  scanf (" %[^\n]", str);

  start_ptr = strlen (str) - 1;

  end_anchor = start_ptr;
  state = 0;
  while (start_ptr >= -1)
  {
    switch (state)
    {
      case 0:
             if ((!isspace (str[start_ptr]) && (start_ptr >= 0)))
             {
               start_ptr--;
             }
             else
             {
               state = 1;
             }
             break;

      case 1:
             show_string (str, start_ptr + 1, end_anchor);
             state = 2;
             start_ptr--;
             printf (" ");
             break;

      case 2:
             if (!isspace (str[start_ptr]))
             {
               state = 0;
               end_anchor = start_ptr;
             }
             else
             {
               start_ptr--;
             }
             break;
    }
  }


  printf ("\n");
  return 0;
}

The end_anchor points to each end word, and the start_ptr finds the start of the word of which the end is held by end_anchor. When we find a word start (by blankspace characters or start_ptr = -1), we print all the characters from start_ptr + 1 to end_anchor. The + 1 is because of the implementation: start_ptr points to the blankspace character, and the print routine will print all the characters from i to n. Once we have detected one blank space we print it and we skip adjacent blankspaces (in case 2) and preserve only one which is manually printed. Once a non blankspace is detected, we have got another word end, for which we set the end_anchor to this index in the case 2, and set state = 0 , so that we can search for the word start again.

if(words[i] != ' ') 
    wordstart = i;

This statement what about the else part? if words[i] == ' ', and wordstart remains -1. So maybe try to use:

while (words[i] && words[i] == ' ') ++i;
  if (!words[i])
      break;
wordstart = i;

Then you should output the result out of the i loop. Finally, if you want to get the result you expected, you should reverse the whole sentence once more, with the way you used in the loop.

I would use write function similar to strrchr for finding last occurence of ' ', if its found print word that follows, rewrite this ' ' with '\0' and repeat it in loop till no more words are found. At the end I would print the content of this string again because there is most likely no ' ' before the first word.

I would write own function instead of strrchr because strrchr calculates the lenght of the given string, which is redundant in this case. This length doesn't have to be calculated more than once.

Here's the code:

char* findLastWord(char* str, int* len)
{
    int i;
    for (i = *len - 1; i >= 0; --i)
    {
        if (str[i] == ' ')
        {
            str[i] = '\0';
            if (i < *len - 1)
            {
                *len = i - 1;
                return &str[i + 1];
            }
        }
    }
    return NULL;
}

int main (int argc, char *argv[])
{
    char str[] = " one two three  four five six ";
    int len = strlen(str);

    char* lastWord = findLastWord(str, &len);
    while (lastWord != NULL)
    {
        printf("%s\n", lastWord);
        lastWord = findLastWord(str, &len);
    }
    if (len > 1)
        printf("%s\n", str);
    return 0;
}

output:

six
five
four
three
two
one

Hope this helps ;)

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

void reverse(char *str, size_t len)
{
    char tmp;
    size_t beg, end;
    if (len <=1) return;

    for (beg=0,end=len; beg < --end ; beg++) {
        tmp = str[beg];
        str[beg] = str[end];
        str[end] = tmp;
    }
}

int main(void)
{
    char sentence[] = "one two three four five";
    size_t pos, len;

    printf("Before:%s\n",sentence);
    for (pos = len= 0;  sentence[pos]; pos += len) {
        pos += strspn( sentence+pos, " \t\n" );
        len = strcspn( sentence+pos, " \t\n" );
        reverse ( sentence + pos, len );
        }
    reverse ( sentence , pos );

    printf("After:%s\n",sentence);

    return 0;
}
 #include <iostream>
 #include <string>   
  using namespace std;
  char* stringrev(char s[], int len)
  {
    char *s1 = (char*)malloc(len+1);
    int i=0;
    while (len>0)
    {
      s1[i++] = s[--len];
    }
   s1[i++] = '\0';
    return s1;   
  }

   void sentrev(char s[], int len)
 {
    int i=0; int j=0;
     char *r = (char*)malloc(len+1);
     while(1)
     {
     if(s[j] == ' ' || s[j] == '\0')
     {
       r = stringrev(s+i, j-i);
       i = j+1;
       cout<<r<<" ";
     }
    if (s[j] == '\0')
    break;
    j++;
   }

 }


int main()
{
char *s = "this is a test";
char *r = NULL;
int len = strlen(s);
cout<<len<<endl;
r = stringrev(s, len);
cout<<r<<endl;
sentrev(r, len);
return 0;
}

The above code snap reverse the sentence, using char *r and printing cout<

#include<stdio.h>
#include<conio.h>
#include<string.h>
int main()
{
char st[50], rst[50];
printf("Enter the sentence...\n");
gets(st);
int len=strlen(st), p;
int j=-1,k;
p=len;
for(int i=(len-1); i>=0; i--)
{
    //searching for space or beginning
    if(st[i]==' ')
    {
        //reversing and storing each word except the first word
        for(k=i+1;k<p;k++)
        {
            //printf("%c",st[k]);
            rst[++j]=st[k];
        }
        j++;
        rst[j]=' ';
        printf("\n");
        p=i;
    }
    else if(i==0)
    {
        //for first word
        for(k=i;k<p;k++)
        {
            //printf("%c",st[k]);
            rst[++j]=st[k];
        }
    }

}
printf("Now reversing the sentence...\n");
puts(rst);
return 0;
}
sandy

Use a main for loop to traverse till the end of the sentence: Copy the letters in a string until you find a space. now call add@beginning function and in that function add the string each time you pass a string to the linked list. print the contents of the linked list with a space inbetween to get the expected output

My code,just traverse from the last and if you find a space print the characters before it,now change the end to space-1;This will print till the second word,finally just print the first word using a single for loop.Comment for alter approach.

Program:

#include<stdio.h>
int main()
{
 char str[200];
int i,j,k;
scanf("%[^\n]s",&str);
for(i=0;str[i]!='\0';i++);
i=i-1;
for(j=i;j>=0;j--)
{
    if((str[j])==' ')
    {
        for(k=j+1;k<=i;k++)
        {
            printf("%c",str[k]);
        }
        i=j-1;
        printf(" ");
    }

}
for(k=0;k<=i;k++)
{
    printf("%c",str[k]);
}
}
using stack 

#include <iostream>  
#include <stdio.h>
#include <stack>

int main()
{ 

    std::stack<string> st;
    char *words= "this is a test";
    char * temp =   (char *)calloc(1, sizeof(*temp));
    int size1= strlen(words);
    int k2=0;
    int k3=0;
    for(int i=0;i<=size1;i++)
    {
       temp[k2] = words[i];
       k2++;
        if(words[i] == ' ')     
        {  
            k3++;
            if(k3==1)
                temp[k2-1]='\0';

            temp[k2]='\0';
            st.push(temp);
            k2=0;           
        }
        if(words[i] == '\0')
        {
            temp[k2]='\0';
            st.push(temp);
            k2=0;
            break;
        }               
    }

  while (!st.empty())
  {
       printf("%s",st.top().c_str());
        st.pop();
  }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!