• C

string manipulation

How to write a C program ? If I input a string e.g. This is a demonstration
then the program will display
sihT si a noitartsnomed

That is reserve the words the user inputted.
adrianmakAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

laeuchliCommented:
I think you are looking for
#include <conio.h>
#include <ctype.h>

void main( void )
{
   int ch;

   _cputs( "Type 'Y' when finished typing keys: " );
   do
   {
      ch = _getch();
      ch = toupper( ch );
   } while( ch != 'Y' );

   _putch( ch );
   _putch( '\r' );    /* Carriage return */
   _putch( '\n' );    /* Line feed       */
}

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
C_DreamerCommented:
In C, main returns int.
The questioner did not specify his platform, so how do you know that conio.h is available to him? Or _putch()? Or _getch()?

Here's a better implementation:

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

void revstr(char *s)
{
  int i, j;
  char tmp;

  if(s != NULL)
    for(i = 0, j = strlen(s) - 1;
        i < j;
        i++, j--)
    {
      tmp = s[i];
      s[i] = s[j];
      s[j] = tmp;
    }
}

int main(void)
{
  char buffer[1024];
  char *p;

printf("Type in some stuff,\n");
printf("then press ENTER\n");
printf("In DOS, press ^Z to finish.\n");
printf("In UNIX, ^D (I think).\n");


  while(fgets(buffer, sizeof buffer, stdin) != NULL)
  {
    p = strchr(buffer, '\n');
    if(p != NULL)
      *p = '\0';

    revstr(buffer);
    printf("%s\n", buffer);
  }

  return 0;
}

(Caution: not compiled or tested. Nevertheless, I'm fairly confident it'll work)
0
adrianmakAuthor Commented:
C dreamer,

I think you not understand my requirement

I want the input string to display
input string:
This is a demo

Then the output string is:
sihT si a omed

but no
omed a si sihT


0
Powerful Yet Easy-to-Use Network Monitoring

Identify excessive bandwidth utilization or unexpected application traffic with SolarWinds Bandwidth Analyzer Pack.

C_DreamerCommented:
Yep, I missed that. You are looking for word-by-word reversal, not line by line reversal.

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

/* this bit can stay the same */
void revstr(char *s)
{
  int i, j;
  char tmp;

  if(s != NULL)
    for(i = 0, j = strlen(s) - 1;
        i < j;
        i++, j--)
    {
      tmp = s[i];
      s[i] = s[j];
      s[j] = tmp;
    }
}

int main(void)
{
  char buffer[1024];
  char *token;

printf("Type in some stuff,\n");
printf("then press ENTER\n");
printf("In DOS, press ^Z to finish.\n");
printf("In UNIX, ^D (I think).\n");

  while(fgets(buffer, sizeof buffer, stdin) != NULL)
  {
    token = strtok(buffer, " \t\n");
    while(token != NULL)
    {
      revstr(token);
      printf("%s ", token);
      token = strtok(NULL, " \t\n");
    }
    printf("\n");
  }

  return 0;
}

Apologies for misreading the spec (more haste, less speed).
0
adrianmakAuthor Commented:
C dreamer,

the strtok C function seems not a standard C function. Please rewrite using standard C function
0
C_DreamerCommented:
The strtok function has been ANSI standard C since the first ANSI standard was introduced. Here is the entry for it from the most recent standard (draft copy, and apologies in advance for formatting, or rather the lack thereof). Because strtok is standard, your comment that it seems not to be is incorrect, and there is no need for a rewrite):

       7.21.5.8  The strtok function

       Synopsis

       [#1]

               #include <string.h>
               char *strtok(char * restrict s1,
                       const char * restrict s2);

       Description

       [#2] A sequence of calls to the strtok function  breaks  the
       string  pointed  to by s1 into a sequence of tokens, each of
       which is delimited by a character from the string pointed to
       by  s2.  The first call in the sequence has a non-null first
       argument; subsequent calls in the sequence have a null first
       argument.   The  separator  string  pointed  to by s2 may be
       different from call to call.

       [#3] The first call in  the  sequence  searches  the  string
       pointed  to  by  s1  for  the  first  character  that is not
       contained in the current separator string pointed to by  s2.
       If  no  such character is found, then there are no tokens in
       the string pointed to by s1 and the strtok function  returns
       a  null  pointer.   If  such a character is found, it is the
       start of the first token.

       [#4] The strtok function then  searches  from  there  for  a
       character that is contained in the current separator string.
       If no such character is found, the current token extends  to


       7.21.5.6                   Library                  7.21.5.8




       WG14/N869   Committee Draft  --  January 18, 1999        379


       the  end  of  the  string  pointed  to by s1, and subsequent
       searches for a token will return a null pointer.  If such  a
       character  is  found, it is overwritten by a null character,
       which terminates the current  token.   The  strtok  function
       saves  a  pointer to the following character, from which the
       next search for a token will start.

       [#5] Each subsequent call, with a null pointer as the  value
       of  the  first  argument,  starts  searching  from the saved
       pointer and behaves as described above.

       [#6] The  implementation  shall  behave  as  if  no  library
       function calls the strtok function.

       Returns

       [#7]  The  strtok  function  returns  a pointer to the first
       character of a token, or a  null  pointer  if  there  is  no
       token.

       [#8] EXAMPLE 1

               #include <string.h>
               static char str[] = "?a???b,,,#c";
               char *t;

               t = strtok(str, "?");   // t points to the token "a"
               t = strtok(NULL, ",");  // t points to the token "??b"
               t = strtok(NULL, "#,"); // t points to the token "c"
               t = strtok(NULL, "?");  // t is a null pointer

0
daks2003Commented:
Hi,
This might be of some help.

#include<stdio.h>
void printrev(char *str)
{
  char *stpos, *endpos;
/* access all the chars in the string */
  for(stpos=str; *str!='\0'; str++)
     {
     /* when a word is inished */
     if(*str == ' ')
        {
         /* from end of the word goto the begnning of the word */
         for(endpos=str; endpos>=stpos; endpos--)
           printf("%c", *endpos);
        }
/* mark the beginning for next word */
      stpos = str+1;

/* take care of multiple spaces between words */
      for(;*str==' '; str++)
            ;
        }
}

I have not tested this function. But still should work.
0
C_DreamerCommented:
If str is NULL, this function invokes undefined behaviour.

When I tested it with this driver:

int main(void)
{
  char buffer[100];
  while(fgets(buffer, sizeof buffer, stdin))
  {
    printrev(buffer);
  }
  return 0;
}

and gave it perfectly normal input, it didn't work at all. So how exactly does it help, and how does this non-working solution improve upon a working solution?
0
PacmanCommented:
looks like homework ....
0
adrianmakAuthor Commented:
it works but if I don't use any string function then how ?
0
adrianmakAuthor Commented:
c dreamer,

Below is the reverse word function without using any C string functions

Do you have any comment to the code ?
Is there any optimization do for the code ?


void ReverseWord(char *str)
{  int len,i,j,m,n;
   char revword[50];

      len=0; j=0; i=0; m=0; n=0;
      while (str[len]!='\0')
        len++;

      while ((i<=len) && (str[len-1]!='\0'))
      {  while ((str[j]!=' ') && (str[j]!='\0'))
            j++  ;
        for (m=i,n=j-1;n>=i;m++,n--)
           revword[m]=str[n];
        revword[j]=' ';

        j=i=m+1;
       }
      revword[len]='\0';
      printf("\n%s",revword);
}
0
C_DreamerCommented:
(a) If the string passed in is empty (i.e. ""), len will be 0, and so str[len - 1]!='\0') invokes undefined behaviour (referring to memory not owned).

(b) This version of the function seems needlessly complicated. I won't suggest a simpler one, because I already have done.

(c) If the input string is greater than 50 characters, the behaviour is undefined.

(d) str[len - 1] is always the same (because you never change str or len) so it's puzzling to see it as part of the while loop.

(e) if you don't end a printf format string with \n, you should explicitly flush the standard output stream using fflush(stdout), to ensure that the output appears at the expected point.

Given all those points, I haven't gone so far as to check whether the function would work if they were fixed, as it seems rather pointless.

0
adrianmakAuthor Commented:
here is my main() function
void main()
{  char s[50], choice;


 while ((choice!='Q') && (choice!='q'))
 {  clrscr();
    printf("\nEnter a string: ");
    gets(s);

    printf("\nS - Reverse string");
    printf("\nW - Reverse words");
    printf("\nF - Find substrinf");
    printf("\nC - Count number of vowels, consonants and other symbols");
    printf("\nQ - To Quit");
    choice=getc(stdin);

    switch (choice)
    { case 'S': ReverseStr(s); break;
      case 's': ReverseStr(s); break;
      case 'W': ReverseWord(s); break;
      case 'w': ReverseWord(s); break;
      case 'F': FindSubstr(s); break;
      case 'f': FindSubstr(s); break;
      case 'C': countvowel(s); break;
      case 'c': countvowel(s); break;
      case 'Q': break;
      case 'q': break;
      default : printf("Invalid input...try again"); break;
   };
   delay(2000);
 };
}

The problem is on the 1st cycle of the while loop, it can ask me to input a string s at the gets(s) statement but after doing some function in the case statement and back to the beginning of the loop, it skip the gets(s) statement (ie not asking me to input a string again).
Why ?

0
C_DreamerCommented:
1) main returns int, not void. We covered that earlier in this thread.
2) stdin is line-buffered, so your getc call waits for a newline character before returning control to your program. The choice you made is processed as you expect, but there's still that newline sitting in the buffer, so gets() takes this as its own input, which is why it isn't waiting for you.
3) gets() cannot be used safely, as there is no way it can prevent your buffer being overflowed by an overenthusiastic typist (or a malicious cracker). Exploitation of gets() was how the infamous Internet Worm worked. Never use gets(). Use fgets() instead.
4) If you #include <ctype.h> you can switch on toupper(choice) instead of just choice, which will save you some code.
5) if you want printf to guarantee to produce your output at the time you expect, either end your format string with a \n, or fflush(stdout) after the printf.
6) main returns int, so add return 0; at the bottom of main.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.