Thread: String editor for a sentence inputted by a user - any suggestions or ideas?

  1. #1
    Registered User
    Join Date
    Feb 2006
    Posts
    3

    Talking String editor for a sentence inputted by a user - any suggestions or ideas?

    To everyone out there,

    I have this program in mind that manipulates a string keyed in by a user. Here's what the program is supposed to do…

    I am to enter a string into an array and then manipulate this string by..
    a) Deleting any word or character in that string
    b) Insert any word or character anywhere in the string I previously entered (while displaying its position in the string)
    c) Search any word or character present in the string that was previously entered

    Its sample run goes like this...

    Enter source string: Internet use is growing rapidly.
    (it goes into this array that I've declared <I put this array in imaginary boxes to illustrate the idea, including the spaces>)

    |I|n|t|e|r|n|e|t| |u|s|e| |i|s| |g|r|o|w|i|n|g| |r|a|p|i|d|l|y|.|\0|

    (Then a menu appears below it...)
    Choose from the Menu
    D <Delete>
    I <Insert>
    F <Find>
    Q <Quit>
    choice: _


    (When the user keys in a preferred action, this is what each choice is supposed to do...)
    (if F <Find>)
    String to search: .
    " . " found at position 23
    (what happens to the array->)
    |I|n|t|e|r|n|e|t| |u|s|e| |i|s| |g|r|o|w|i|n|g| |r|a|p|i|d|l|y|.|\0|
    string to search: - |.|
    at what position: 23
    display >> "." found at position 23


    (if F <Find>)
    String to search: use
    "use" found at position 9
    (what happens to the array->)
    |I|n|t|e|r|n|e|t| |u|s|e| |i|s| |r|a|p|i|d|l|y| |e|x|p|a|n|d|i|n|g|.|\0|
    string to search: - | |u|s|e| |
    at what position: 9
    display >> "use" found at position 9


    (if I <Insert>)
    String to insert: expanding
    Position of insertion: 23
    New string: Internet use is rapidly expanding.
    (what happens to the array->) |I|n|t|e|r|n|e|t| |u|s|e| |i|s| |r|a|p|i|d|l|y|.|\0|
    string to insert: -| |e|x|p|a|n|d|i|n|g| |
    at what position: 23
    new string:-
    |I|n|t|e|r|n|e|t| |u|s|e| |i|s| |r|a|p|i|d|l|y| |e|x|p|a|n|d|i|n|g|.|\0|


    (if D <Delete>)
    String to delete: growing
    New string: Internet use is rapidly.
    (what happens to the array->)
    |I|n|t|e|r|n|e|t| |u|s|e| |i|s| |g|r|o|w|i|n|g| |r|a|p|i|d|l|y|.|\0|
    string to delete: -| |g|r|o|w|i|n|g| |
    new string:-
    |I|n|t|e|r|n|e|t| |u|s|e| |i|s| |r|a|p|i|d|l|y|.|\0|


    I made up the steps for some of the menu functions in English (along with a C source line) but I'm not sure if these are correct…

    I) Search any word or character present in the string that was previously entered (Find function)
    - get string to search <
    Code:
    gets (search_str)
    >
    - from the beginning of the main string, until it is not the end of the main string, increment forward
    <
    Code:
    (i =0; i < main_str [80]; i++)
    >
    a) compare lengths of the string to search and the main string
    <
    Code:
    if ((strcmp (searchstr, main_str)) == 0)
          found = 1;
    >
    If match is found <
    Code:
     if (found)
    >
    a) Note position of the first letter of the word or the single character then display it and the word or character to the screen.
    <
    Code:
    printf (" \" %s \" found at position %d", searchstr, main_str[i] );
    >
    Else
    a) say that a the string to search does not exist.
    <
    Code:
    printf ("The word you want to search does not exist");
    >


    II) Delete any word or character present in the string that was previously entered (Delete function)
    - get string to delete <
    Code:
    gets (del_str)
    >
    - from the beginning of the main string, until it is not the end of the main string, increment forward
    <
    Code:
    (i =0; i < main_str [80]; i++)
    >
    a) compare lengths of the string to delete and the main string
    <
    Code:
    if ((strcmp (searchstr, main_str)) == 0)
          found = 1;
    >
    if match is found < if (found) >
    a)Turn each character of the main string that matches the character of the substring into a
    space
    <
    Code:
     *strptr [ i - 1] = ' ';
    >
    b)Transfer each element of the main string array into a new array of the same size named, newstring.
    <
    Code:
    strcpy (main_str, newstring);
    >
    c)Display the contents of the array containing the modified main string to the screen
    <
    Code:
    printf ("New string: %s", newstring);
    >
    else
    a) say that the string to delete does not exist.
    <
    Code:
    printf ("The word you want to delete does not exist");
    >


    I can't think of a way to get the Insert function - I'm stumped for ideas on it , I'd be so dead grateful if you have any.

    I'd welcome any suggestions for my post above (if you can provide some C source lines, please do).


    Respectfully yours,
    the_newbug

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >gets (search_str)
    gets is unsafe. You would be better off with fgets:
    Code:
    fgets ( search_str, sizeof search_str, stdin );
    >from the beginning of the main string, until it is not the end of the
    >main string, increment forward
    The standard library has a function called strstr that does all of the hard work of searching for you.

    >(i =0; i < main_str [80]; i++)
    Unless main_str[80] contains the length of the array, this probably won't work. A better solution is to use the return value of strlen to tell you exactly how long the string is:
    Code:
    int len = strlen ( main_str );
    for ( i = 0; i < len; i++ )
    >if ((strcmp (searchstr, main_str)) == 0)
    This won't compare the search string with the current index being searched, you need to take the address of the character that you're at in the search:
    Code:
    if ( strcmp ( search_str, &main_str[i] ) == 0 )
      fount = 1;
    A search algorithm could look like this:
    Code:
    if ( fgets ( search_str, sizeof search_str, stdin ) != NULL ) {
      char *match = strstr ( main_str );
    
      if ( match != NULL )
        printf ( " \"%s\" found at position %d", search_str, match - main_str );
      else
        printf ("The word you want to search does not exist");
    }
    Your deletion algorithm is questionable, and it can be as simple as shifting characters N spaces to the left where N represents the length of the deleted substring:
    Code:
    if ( fgets ( search_str, sizeof search_str, stdin ) != NULL ) {
      char *match = strstr ( main_str );
    
      if ( match != NULL ) {
        int len = strlen ( search_str );
        memmove ( match, match + len, len );
      }
      else
        printf ("The word you want to delete does not exist");
    }
    >I can't think of a way to get the Insert function
    Insertion is the inverse of deletion. You just need to make sure that the new string isn't longer than the array can hold. Give it a try and see if you can work out something.
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Feb 2006
    Posts
    3

    Sorry if it's only now I've replied to your post...

    To Prelude,

    Sorry if it's only now I've replied to your post - been studying over the source lines you gave me. By the way, there are some things I wish to know about them...

    - What are the advantages of using the function "fgets" over "gets"? (as in the case of this program)

    - Could you please explain how does the function "memmove" act on this line...
    Code:
    memmove ( match, match + len, len );
    If you were to make your own version of the 'memmove' function, what would it look like? (Could you also please include a pseudocode of it?)

    - If I were to make my own version of the function strstr, would it look like the one below?
    Code:
    //Program to find an input substring in an input main string
    
    void main()
    {
     int i=0;
     int j=0;
     int k=0;
     int l=0;
     int k1=0;
     char a[80],b[80];
    
     clrscr();
     printf("Enter main string:- ");
     gets(a);
     printf("Enter sub-string:-");
     gets(b);
    
     l=strlen(b);
     while (a[i]!=EOF) do
           {
            if (a[i]==b[j])
               {
                i++;
       	    j++;
       	    k1=1;
               } 
             else
               {
       	    if (k1==1)
       	       {
        		j=0;
        		k1=0;
       	       }
       	     else
                   i++;
               }
           }
    
      if (k==1)
         {
          printf("The given sub-string is present in the main string.");
         }
       else
         {
          if (k==0)
          printf("The given sub-string is not present in the main string.");
         }
     getch();
    }
    And here's my interpretation of the ideas you gave me
    Code:
    //Edits a string
    
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<conio.h>
    #include<string.h>
    #include<alloc.h>
    #include<mem.h>
    
    
    
    //All the functions to use
    //Searches for the string
    char Find(char main_str, int len)
    {
     char search_str;	//The string to delete
     char *match;		//Contains the string that matches the one to search
     
     printf("String to find:");
     if ( fgets ( search_str, sizeof search_str, stdin ) != NULL ) 
        {
         char *match = strstr ( main_str );
        
         if ( match != NULL )
            printf ( " \"%s\" found at position %d", search_str, match - main_str );
          else
            printf ("The word you want to search does not exist");
        }
     getch();
     return new_str;
    }
    
    
    //Deletes the string
    char Erase(char main_str, int len)
    {
     char del_str;		//The string to delete
     char *del_match;	//Contains the string that matches the one to delete
     char new_str;		//Displays the new string
     int delstr_len;	//length of the string to delete
    
     printf("String to delete:  ");
     if ( fgets ( search_str, sizeof search_str, stdin ) != NULL ) 
        {
         del_match = strstr (main_str);
         if ( del_match != NULL ) 
            {
             delstr_len = strlen ( search_str );
             new_str = memmove ( del_match, del_match + len, len );
             printf ("New source: %s \n", new_str);
            }
          else
            printf ("The word you want to delete does not exist");
        }
     getch();
     return new_str;
    }
    
    
    //Inserts the string - the one you wanted me to try coding on
    char Insert(char main_str,int len)
    {
     int sub_len, total_len;	//variables to use in this function
    
     printf("String to insert: ");
     fgets(sub_str, sizeof sub_str, stdin);	// gets the string from the user
     
     sub_len = strlen (sub_str);		//gets the length of the string to insert
     
     printf("\nPosition of insertion>   ");
     scanf("%d", &pos);			//gets the position as to where to place the string on the main string
     
     total_len = len + sub_len;		//gets the total length of the two strings to use...
     
     char newstring[total_len];		//...as the basis for the length of this array that will hold both of them
     
      // from the starting point of insertion on main_str up to the end of sub_str, insert subtring while incrementing forward
     	for (i=main_str[pos]; i<sub_str[n-1]; i++)	
    						   //does "sub_str[n-1]" access the tail end of sub_str?
    
         newstring = strcat (main_str, sub_str);	//starts inserting the sub_str into main_str using the strcat function
     printf("New source:  %s \n",newstring);	//prints out the string
     
     getch();
     return newstring;
    }
    
    
    
    //the program proper
    void main(void)
    {
     char main_str;		//the first string that the user types in
     int len;		//length of main string
     int choice;		//menu choice number
    
     do
      {
       do
        {		//the menu proper
         clrscr();
         printf("Please type in a sentence:  ");
         fgets(main_str, sizeof main_str, stdin);    //gets main_str
         len = strlen (main_str);       //gets the length of main_str
    
         printf ("\n");
         printf("[1] Find \n");
         printf("[2] Delete \n");
         printf("[3] Insert \n");
         printf("[4] Exit\n \n");
         printf ("\n");
         printf("Enter number of your choice:");
         scanf("%d",&choice);
        } while (choice <1 || choice>4);
    	    switch(choice)
    		  {
    		   case 1:
    			  Find();
    			  break;
    		   case 2:
    			  Erase();
    			  break;
    		   case 3:
    			  Insert();
    			  break;
    		  }
      } while (choice != 4);
    }
    I hope I got your ideas right - well, I'm open to learn new things. Just tell me if I overlooked something.

    Thanks.

    Respectfully yours,
    the_newbug
    Last edited by the_newbug; 03-02-2006 at 04:24 AM. Reason: forgot to add something to my reply

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >What are the advantages of using the function "fgets" over "gets"?
    fgets is safe and gets is not. Look at it this way, you pass gets a buffer, but not a buffer size, so what happens if the user gives you more input than the buffer can hold? gets doesn't know any better, so it happily writes to memory until the end of input, even if the memory is beyond the boundaries of your buffer. That's called buffer overflow, and many bad things happen when you do it.

    >Could you please explain how does the function "memmove" act on this line...
    memmove is a safe version of memcpy when the source and destination overlap. You can think of it as a loop that always does the right thing, but does roughly the following:
    Code:
    int i;
    unsigned char *src = match + len;
    unsigned char *dst = match;
    
    while ( --len >= 0 )
      *src++ = *dst++;
    If you were to make your own version of the 'memmove' function, what would it look like?
    Code:
    char *memmove ( void *dst, const void *src, int n )
    {
      char *s = src;
      char *d = dst;
    
      if ( s < d && ( d < s + n ) ) {
        d += n;
        s += n;
    
        while ( --n >= 0 )
          *--d = *--s;
      }
      else {
        while ( --n >= 0 )
          *d++ = *s++;
      }
    
      return dst;
    }
    >If I were to make my own version of the function strstr, would it look like the one below?
    No, but it's a good start.

    >void main()
    main returns int. This is your template for main taking no arguments:
    Code:
    int main ( void )
    {
      return 0;
    }
    This is your template for main taking arguments:
    Code:
    int main ( int argc, char *argv[] )
    {
      return 0;
    }
    Anything else is implementation defined, and not guaranteed to work.
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Feb 2006
    Posts
    3

    Thanks for the ideas!

    Thanks for the ideas!
    By the way, there is something I forgot to ask you. You told me to code the Insert function and I made one. What do you think of it?

    The insert string function - the one you wanted me to try coding
    Code:
    		
    //Inserts the string 
    
    char Insert(char main_str,int len)
    {
     int sub_len, total_len;
    		
     printf("String to insert: ");
     fgets(sub_str, sizeof sub_str, stdin);		
     
     sub_len = strlen (sub_str);			
     
     printf("\nPosition of insertion>   ");
     scanf("%d", &pos);				
     
     total_len = len + sub_len;			
     
     char newstring[total_len];			
     
     for (i=main_str[pos]; i<sub_str[n-1]; i++)	
          newstring = strcat (main_str, sub_str);	
    
     printf("New source:  %s \n",newstring);	
     
     getch();
     return newstring;
    }
    Here's a line-by-line description of it

    The function call with the external variables
    Code:
    char Insert(char main_str,int len)
    These are the variables to use in this function
    Code:
     int sub_len, total_len;
    Gets the string from the user
    Code:
     printf("String to insert: ");
     fgets(sub_str, sizeof sub_str, stdin);
    Gets the length of the string to insert
    Code:
    sub_len = strlen (sub_str);
    Gets the position as to where to place the string on the main string
    Code:
    printf("\nPosition of insertion>   ");
     scanf("%d", &pos);
    Gets the total length of the two strings to use...
    Code:
    total_len = len + sub_len;
    ...as the basis for the length of this array to be declared within the function that will hold both of them
    Code:
    char newstring[total_len];
    Then, from the starting point of insertion on main_str up to the end of sub_str, insert subtring while incrementing forward
    Code:
    for (i=main_str[pos]; i<sub_str[n-1]; i++)
    Does this code phrase access the tail end of sub_str?
    Code:
    sub_str[n-1]
    Starts inserting the sub_str into main_str using the strcat function
    Code:
    newstring = strcat (main_str, sub_str);
    Finally, it prints out the string
    Code:
    printf("New source:  %s \n",newstring);

    I hope I got hold of the ideas you told me - I really admire expert programmers like you. You seem to get hang of translating your ideas in English language to C source code so easily.


    Yours truly,
    the_newbug
    Last edited by the_newbug; 03-03-2006 at 02:21 AM. Reason: Some final touches - if you may allow

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. Calculator + LinkedList
    By maro009 in forum C++ Programming
    Replies: 20
    Last Post: 05-17-2005, 12:56 PM
  3. Another overloading "<<" problem
    By alphaoide in forum C++ Programming
    Replies: 18
    Last Post: 09-30-2003, 10:32 AM
  4. "Operator must be a member function..." (Error)
    By Magos in forum C++ Programming
    Replies: 16
    Last Post: 10-28-2002, 02:54 PM