Thread: Using Strings with Functions

  1. #1
    Registered User
    Join Date
    Oct 2001
    Posts
    4

    Using Strings with Functions

    I am unclear on how to get string functions to talk to the main program. What I am trying to do is take a sentence, then return it with all blanks removed. Has to be done within a function.
    Where am I going wrong?
    See code below.

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


    char *noblank(char *, int);

    void main ()
    {

    char sentence[80];
    int i, length;
    char *dest;

    printf("enter a sentence> \n");
    gets(sentence);
    length = strlen(sentence);
    printf("length is %d\n", length);
    dest =*noblank(&sentence, length);
    printf("%s\n", dest);
    }
    char *noblank(char *sentence, int length)

    {
    int i;
    int newlen = length+1;
    char dest[newlen];
    for (i = 0; i != ' ' && i != '\n' && i < newlen; ++i)
    dest[i++] = getchar();
    dest[i] = '\0';
    return (dest);
    }

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    First of all, main always returns an int so it is" int main()" NOT "void main()"!!

    Second, I am unfamiliar with the calling convention "dest = *noblank...." so I will address this ignoring that.

    There are two approaches you might try: pass the destination string as a parameter to noblank, or just change the original string within the function and return it in it's changed form. I'll illustrate the second method:

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


    void noblank(char *);

    int main ()
    {

    char sentence[81];
    int i, length;

    printf("enter a sentence> \n");

    fgets(sentence, 80,stdin);

    noblank(sentence); // or even "noblank(&sentence[0]);"

    printf("%s\n", sentence);
    }





    void noblank(char *string)

    {
    int i,j=0;
    int newlen = strlen(string)+1;
    char temp[newlen];
    for (i = 0; i != ' ' && i != '\n' && i < newlen; ++i)
    {
    temp[j] = string[i];
    j++;
    }
    strcpy(string,temp);
    }


    __________________

    I also noticed you try to access "length" within the function. Don't do that because 1)length is not global 2)length should not be global anyway 3)You add an unnecessary parameter to your function when the function can just as well find the length of "sentence".
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Ok, fine - you reply while I think about it

    So now I can fix yours instead

    > First of all, main always returns an int
    So do it - don't just say it.
    Your example shuffles uneasly off the end of the function.

    > fgets(sentence, 80,stdin);
    Why the size difference?
    fgets ( sentence, sizeof(sentence), stdin );
    works just as well, and you don't have to think "now does this allow for \0 or not".

    > char temp[newlen];
    This isn't even valid 'C' - you can't declare arrays with variable length. To do this, you would need to call malloc.

    The important thing to realise about this problem is that the new string can never be longer that the old string, so I would think it would be ok to re-use it in place.

    Code:
    #include <stdio.h>
    
    void noblank(char *string) { 
        int i, j;
        for ( i = 0, j = 0 ; string[i] != '\0' ; i++ ) {
            if ( string[i] != ' ' ) string[j++] = string[i];
        }
        string[j] = '\0';
    }
    
    int main ( ) {
        char    test[] = "hello world";
        noblank( test );
        printf( "%s\n", test );    
        return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    OK smartypants!

    > First of all, main always returns an int
    >So do it - don't just say it.
    >Your example shuffles uneasly off the end of the function.

    Simple Typo...

    > fgets(sentence, 80,stdin);
    >Why the size difference?
    >fgets ( sentence, sizeof(sentence), stdin );
    >works just as well, and you don't have to think "now does this >allow for \0 or not".

    If the string is 80 in length, that means 79 chars and a '\0' right?
    So if fgets is recieving input from a user who enters 99 chars, it gets 80 of those and no room for the null terminator, right?


    > char temp[newlen];
    >This isn't even valid 'C' - you can't declare arrays with variable >length. To do this, you would need to call malloc.

    Not true, I have used this convention hundreds of times! Perhaps I have a "smart" compiler, Salem!
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    *grumble*

    I must add that your convention of using the same string is quite ingenious, Salem. Kudos!
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    24
    i DON'T INDERSTAND THAT WHAT IS meant by "blank".
    are u talking about spaces that we use to seperate one word to another? that means the ascii code of that is 32. m i right?
    RaHaTk

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > are u talking about spaces that we use to seperate one word to another?
    Yes
    Though blanks can also include tabs and newlines.

    > that means the ascii code of that is 32
    That's the one.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    >> are u talking about spaces that we use to seperate one word
    >> to another?
    >
    > Yes
    > Though blanks can also include tabs and newlines.

    This is why we have "isspace()". This function returns "true" if the character is any form of "white space", as Salem described.

    Quzah.

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    4
    Salem,

    That worked!
    However, I did not mention that I was supposed to make a copy of the sentence, not remove the blanks from the original.

    Here is my modified code, which does work, although it gives me a warning. Thanks so much!

    And thanks also Sebastiani--you will notice some of your ideas in here too!


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

    void noblank(char *);

    int main ( ) {
    char test [100]; /*original sentence */
    char copy [100]; /*copy of sentence */
    printf("enter a sentence>\n");

    fgets(test, sizeof(test), stdin);
    strcpy(copy, &test);
    noblank(copy);
    printf( "%s\n ", test);
    printf( "%s\n ", copy);
    return 0;
    }

    void noblank(char *string) {
    int i, j;
    for ( i = 0, j = 0 ; string[i] != '\0' ; i++ ) {
    if ( string[i] != ' ' ) string[j++] = string[i];
    }
    string[j] = '\0';
    }

  10. #10
    Registered User
    Join Date
    Oct 2001
    Posts
    24
    Then we should not use only "isspace" function. we should consider if there is any spaces or tabs or any newlines.
    all of the conditions should be checked.
    ....how a user can add a new line to a string if he/she is asked to enter a string?
    RaHaTk

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    > ....how a user can add a new line to a string if he/she is asked
    > to enter a string?

    Short version:
    Code:
    puts("Enter some text. CTRL+Z to end:
    	do
    	{
    		printf("Enter text here. CTRL+Z to stop\n:");
    		fgets( buf, sizeof( buf ), stdin );
    		strcat( buf2, buf );
    	}
    	while( !feof( stdin ) );
    However, for me, this is skipping the first input. Oh well, I don't feel like screwing with it right now. That's basicly how it'd work. I'm sure it's been answered by now by someone else.

    Quzah.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. strings and functions
    By simo_mon in forum C Programming
    Replies: 8
    Last Post: 09-16-2008, 05:18 AM
  2. Passing strings to functions and modifying them
    By diddy02 in forum C Programming
    Replies: 6
    Last Post: 08-11-2008, 01:07 AM
  3. Static member functions more efficient?
    By drrngrvy in forum C++ Programming
    Replies: 6
    Last Post: 06-16-2006, 07:07 AM
  4. Reading strings input by the user...
    By Cmuppet in forum C Programming
    Replies: 13
    Last Post: 07-21-2004, 06:37 AM
  5. Replies: 2
    Last Post: 04-13-2003, 08:40 PM