[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

string manipulation

Posted on 2000-01-22
14
Medium Priority
?
220 Views
Last Modified: 2010-04-15
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.
0
Comment
Question by:adrianmak
14 Comments
 
LVL 5

Accepted Solution

by:
laeuchli earned 120 total points
ID: 2377295
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
 

Expert Comment

by:C_Dreamer
ID: 2378051
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
 

Author Comment

by:adrianmak
ID: 2378403
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
Will You Be GDPR Compliant by 5/28/2018?

GDPR? That's a regulation for the European Union. But, if you collect data from customers or employees within the EU, then you need to know about GDPR and make sure your organization is compliant by May 2018. Check out our preparation checklist to make sure you're on track today!

 

Expert Comment

by:C_Dreamer
ID: 2378756
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
 

Author Comment

by:adrianmak
ID: 2380198
C dreamer,

the strtok C function seems not a standard C function. Please rewrite using standard C function
0
 

Expert Comment

by:C_Dreamer
ID: 2380487
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
 

Expert Comment

by:daks2003
ID: 2384639
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
 

Expert Comment

by:C_Dreamer
ID: 2386102
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
 
LVL 9

Expert Comment

by:Pacman
ID: 2389032
looks like homework ....
0
 

Author Comment

by:adrianmak
ID: 2572464
it works but if I don't use any string function then how ?
0
 

Author Comment

by:adrianmak
ID: 2648286
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
 

Expert Comment

by:C_Dreamer
ID: 2650433
(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
 

Author Comment

by:adrianmak
ID: 2655492
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
 

Expert Comment

by:C_Dreamer
ID: 2655554
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

Featured Post

Will You Be GDPR Compliant by 5/28/2018?

GDPR? That's a regulation for the European Union. But, if you collect data from customers or employees within the EU, then you need to know about GDPR and make sure your organization is compliant by May 2018. Check out our preparation checklist to make sure you're on track today!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
There's never been a better time to become a computer scientist. Employment growth in the field is expected to reach 22% overall by 2020, and if you want to get in on the action, it’s a good idea to think about at least minoring in computer science …
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
Suggested Courses

607 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question