Thread: string question

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    62

    string question

    Hi all.

    I don't need help on writing this as much as I have a question.

    Code:
    #include <stdio.h>
    #include <string.h>
    #define MaxStringLength 150
    
    
    int main( int argc, char** agrv)
    {
        char userString[ MaxStringLength + 1 ];
        char c;
        int i;
    
        printf(" Enter a string: ");
        fgets(userString, sizeof(userString), stdin);
    
        printf("    capitalized: ");
        for (i = 0; i < strlen(userString); i++)
        {
            c = userString[i];
            printf( "%c", UpperString(c));
        }
        printf( "\n");
    
        return ( 0 );
    }
    
    UpperString( char *c)
    {
        c = toupper(c);
    }
    My question is should this:
    Code:
    for (i = 0; i < strlen(userString); i++)
    be this:
    Code:
    for (i = 0; i <= strlen(userString); i++)
    It works both ways for me but after being around here for a few weeks I am beginning to think more about efficiency and 'whatif' situations that could break the code.

    Just wondering.

    Thanks

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Code:
    for (i = 0; i < strlen(userString); i++)
    is the proper way to zing through a string. Otherwise, when you read userString[strlen(userString)], you are positioned on the null term character.

    Todd

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You should use:
    Code:
    for (i = 0; i < strlen(userString); i++)
    It works both ways for me but after being around here for a few weeks I am beginning to think more about efficiency and 'whatif' situations that could break the code.
    If you are looking to improve the efficiency, you would save the result of strlen(userString) so that it would not be called on each iteration of the loop. Also, I note that toupper() takes and returns an int, not a pointer to char.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    For a begginner piece of code, it's not bad, but...

    This is not really right:
    Code:
            printf( "%c", UpperString(c));
        }
    ...
    
    UpperString( char *c)
    {
        c = toupper(c);
    }
    Upperstring takes a pointer to char, has no return type, and you are using it as a function that returns a char [presumably] in your call to printf. The compiler should at the very least moan about the conflicting types and/or missing arguments. [You may want to tell your compiler to use "warnings" if you haven't got that already - tell us what compiler you are using]

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Oct 2007
    Posts
    62
    I get the following warnings:


    cap.c: In function `main':
    cap.c:19: warning: implicit declaration of function `UpperString'
    cap.c: At top level:
    cap.c:27: warning: return type defaults to `int'
    cap.c: In function `UpperString':
    cap.c:28: warning: implicit declaration of function `toupper'
    cap.c:28: warning: assignment makes pointer from integer without a cast
    cap.c:29: warning: control reaches end of non-void function

    BTW: using CB

    Ok so it works. That used to be okay for me but now it isn't.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Warnings shouldn't be ignored, although on rare occasions when you use more than one compiler for the same piece of code, you can't completely get rid of ALL warnings [because two compilers complain about different things, and if you fix one thing, the next compiler moans about something else - typically lack of return statements and unreachable code are in that region].

    In this case, all of your warnings can be fixed, mainly by fixing what me and laserlight have pointed out. "UpperString" for example never returns a value, but you are using the return value. You need to declare a prototype for UpperString before main() too [with a return type, which you should repeat at the definition of the function].

    What's "CB" Code::Blocks? In which case it's gcc that's working behind the scenes.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Oct 2007
    Posts
    62
    Alrighty then. First I thank you both.

    Now, I tripped and fell over this:
    Quote Originally Posted by matsp View Post
    You need to declare a prototype for UpperString before main() too [with a return type, which you should repeat at the definition of the function].
    I suppose I need to put:
    Code:
    return (c);
    In UpperString function.

    the declaration of a prototype with a return type before main is what I don't know about.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    A "return type" is something like
    Code:
    int somefunc(int x);
    struct goldmine * someother(float f);
    The red part is a "return type declaration" - it tells the compiler what TYPE the return value has.

    A prototype of a function is essentially the whole line above - it tells the compiler "there is a funciton called <something>, which returns TYPE, and takes whatever parameters you specify". It makes it possible for the compiler to check that you are actually passing the right types back and forth, as well as understanding for example what size the paremeters are.

    There is a different way to do this, and that is to define the function before the use of it, e.g. put the entire UpperString() function ABOVE main. [You still need to add the return type!]

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Oct 2007
    Posts
    62
    I did this and placed it before main():
    Code:
    int UpperString(c)
    {
        c = toupper(c);
        return(c);
    }
    No warnings that I see.

    Thanks Mats

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by tikelele View Post
    I did this and placed it before main():
    Code:
    int UpperString(c)
    {
        c = toupper(c);
        return(c);
    }
    No warnings that I see.

    Thanks Mats
    You may want to specify the type for "c" as well. As it stands, you're using "old" style C which implicitly declares variables as "int". Techically, your argument c and return type are type "char".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Oct 2007
    Posts
    62
    ok i did

    Code:
    int UpperString(char c)
    {
        c = toupper(c);
        return(c);
    }
    I can get away with:
    Code:
    UpperString(char c)
    {
        c = toupper(c);
        return(c);
    }
    can't I?

  12. #12
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    ...but after being around here for a few weeks I am beginning to think more about efficiency and 'whatif' situations that could break the code.
    Do it right. It's not about what you can get away with, it's about the guy following in your footsteps and being able to debug your code. So, it's not about you!!

    And, you still don't have it right.
    Code:
    char UpperString(char c)
    {
        c = toupper(c);
        return(c);
    }
    Todd

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by tikelele View Post
    ok i did

    Code:
    int UpperString(char c)
    {
        c = toupper(c);
        return(c);
    }
    I can get away with:
    Code:
    UpperString(char c)
    {
        c = toupper(c);
        return(c);
    }
    can't I?
    If you don't mind it having a default "int" return type and getting warnings from the compiler - besides, you are returning a "char", which is then converted to int [because you didn't say "char" as the return type].

    None of it will (noticably) affect what the compiler makes of it, just how well it detects when you are trying to be "stupid" about it. And I certainly like any help I can get from the compiler to tell me when I'm being stupid.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    Oct 2007
    Posts
    62
    Quote Originally Posted by Todd Burch View Post
    Do it right. It's not about what you can get away with, it's about the guy following in your footsteps and being able to debug your code. So, it's not about you!!

    And, you still don't have it right.
    Code:
    char UpperString(char c)
    {
        c = toupper(c);
        return(c);
    }
    Todd
    Thanks Todd. Poor choice of words "can I get away with". All I really meant to ask was if I am "over doing" it as in is it necessary to do. I originally had int UpperString (c){ something} and I changed it to int UpperString (char c) { something}, but I inadvertently forgot to change the function type from int to char.

    thanks for all the insight and good advise. I'll be more selective with my word choice.

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by tikelele View Post
    thanks for all the insight and good advise. I'll be more selective with my word choice.
    You'll find that a lot of computer people are VERY pedantic both about meanings of words, and how code should be done. Both, in sensible measures, are good for a programming, as it helps understand documents written by people with a similarly detail-oriented mind, where the difference between "may", "should" and "will" is noticable, as well as being systematic and consistant with upper/lowercase, names, etc, etc will help the reader of some code to understand it more quickly.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

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. Reusing a string pointer question
    By chiefmonkey in forum C++ Programming
    Replies: 3
    Last Post: 05-06-2009, 04:53 PM
  3. Program using classes - keeps crashing
    By webren in forum C++ Programming
    Replies: 4
    Last Post: 09-16-2005, 03:58 PM
  4. String array question
    By gogo in forum C++ Programming
    Replies: 6
    Last Post: 12-08-2001, 06:44 PM