lower case to upper case

Discussion in 'C Programming' started by Janice, Dec 10, 2004.

  1. Janice

    Janice Guest

    char* line = "abcd";
    How to convert the line to upper case and print?
    Any option for printf to do this?
    Thanx
     
    Janice, Dec 10, 2004
    #1
    1. Advertising

  2. Janice

    Ravi Uday Guest

    Janice wrote:
    > char* line = "abcd";
    > How to convert the line to upper case and print?
    > Any option for printf to do this?
    > Thanx
    >
    >


    Not sure if there is a exclusive function in 'C' to do it
    but tivially you could do:

    - Get each character one by one from the input array/string.
    - Check whether the character is lower/upper using 'islower'or 'isupper'
    functions
    - If character is upper case, then Add 32 to get its lower case
    equivalent or
    - If character is lower case Subtract 32 to get its upper case.
    - Store or print the converted characters.

    You might want to do error checking on the input array too if they are
    valid alphabets !

    - Ravi
     
    Ravi Uday, Dec 10, 2004
    #2
    1. Advertising

  3. Ravi Uday <> scribbled the following:
    > Janice wrote:
    >> char* line = "abcd";
    >> How to convert the line to upper case and print?
    >> Any option for printf to do this?
    >> Thanx


    > Not sure if there is a exclusive function in 'C' to do it


    There is. Check out toupper().

    > but tivially you could do:


    > - Get each character one by one from the input array/string.
    > - Check whether the character is lower/upper using 'islower'or 'isupper'
    > functions
    > - If character is upper case, then Add 32 to get its lower case
    > equivalent or
    > - If character is lower case Subtract 32 to get its upper case.
    > - Store or print the converted characters.


    Bzzzt. No one told you you were using ASCII, ISO-8859-1 or any other
    charset where upper and lower case are 32 bytes apart.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-------------------------------------------------------- rules! --------/
    "Stronger, no. More seductive, cunning, crunchier the Dark Side is."
    - Mika P. Nieminen
     
    Joona I Palaste, Dec 10, 2004
    #3
  4. Janice

    Zoran Cutura Guest

    Ravi Uday <> wrote:
    >
    >
    > Janice wrote:
    >> char* line = "abcd";
    >> How to convert the line to upper case and print?
    >> Any option for printf to do this?
    >> Thanx
    >>
    >>

    >
    > Not sure if there is a exclusive function in 'C' to do it
    > but tivially you could do:
    >
    > - Get each character one by one from the input array/string.
    > - Check whether the character is lower/upper using 'islower'or 'isupper'
    > functions
    > - If character is upper case, then Add 32 to get its lower case
    > equivalent or
    > - If character is lower case Subtract 32 to get its upper case.
    > - Store or print the converted characters.
    >
    > You might want to do error checking on the input array too if they are
    > valid alphabets !
    >



    ever heard of tolower/toupper?

    Your suggestions are not portable and will only function on a machine
    where all lower case characters are represented by a value that is by 32
    bigger than the according upper case characters representation. As this
    need not actually be the case the standard provides you with functions
    that need to be supported by your implementations, which makes usage of
    them portable.

    --
    Z ()
    "LISP is worth learning for the profound enlightenment experience
    you will have when you finally get it; that experience will make you
    a better programmer for the rest of your days." -- Eric S. Raymond
     
    Zoran Cutura, Dec 10, 2004
    #4
  5. Janice

    Ravi Uday Guest

    Joona I Palaste wrote:
    > Ravi Uday <> scribbled the following:
    >
    >>Janice wrote:
    >>
    >>>char* line = "abcd";
    >>>How to convert the line to upper case and print?
    >>>Any option for printf to do this?
    >>>Thanx

    >>

    >
    >>Not sure if there is a exclusive function in 'C' to do it

    >
    >
    > There is. Check out toupper().

    Yes it is, missed it some how, Thanks.
    >
    >
    >>but tivially you could do:

    >
    >
    >>- Get each character one by one from the input array/string.
    >>- Check whether the character is lower/upper using 'islower'or 'isupper'
    >> functions
    >>- If character is upper case, then Add 32 to get its lower case
    >> equivalent or
    >>- If character is lower case Subtract 32 to get its upper case.
    >>- Store or print the converted characters.


    To O.P.: the above works for ASCII character set only :)
    >
    >
    > Bzzzt. No one told you you were using ASCII, ISO-8859-1 or any other
    > charset where upper and lower case are 32 bytes apart.
    >
     
    Ravi Uday, Dec 10, 2004
    #5
  6. Janice

    CBFalconer Guest

    Janice wrote:
    >
    > char* line = "abcd";
    > How to convert the line to upper case and print?
    > Any option for printf to do this?


    You can't and no. However if you had defined line as:

    char line[] = "abcd";

    you would have been able to convert it. Now you should spend some
    time thinking about what the difference is. It is fundamental.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Dec 10, 2004
    #6
  7. "Janice" <> wrote in news:cpbs8q$:

    > char* line = "abcd";


    Pointer mis-match, char *line should not point to a const char * "abcd".
    What if "abcd" is placed into non-writable memory?

    > How to convert the line to upper case and print?


    Use a writable array, like CBFalconer suggests, then call toupper() on the
    array.

    > Any option for printf to do this?


    printf("%s\n", name-of-writable-array);

    > Thanx

    Thanks

    --
    - Mark ->
    --
     
    Mark A. Odell, Dec 10, 2004
    #7
  8. Janice

    Eric Sosman Guest

    Mark A. Odell wrote:
    > "Janice" <> wrote in news:cpbs8q$:
    >
    >>char* line = "abcd";

    >
    > Pointer mis-match, char *line should not point to a const char * "abcd".
    > What if "abcd" is placed into non-writable memory?


    No mismatch. The literal creates an array of ordinary
    `char', not `const'-qualified. True, that array cannot be
    written safely, but its type is non-`const' anyhow.

    >>How to convert the line to upper case and print?

    >
    > Use a writable array, like CBFalconer suggests, then call toupper() on the
    > array.


    The argument to toupper() is an `int', not an array.
    And there is no need for a writeable array anyhow:

    char *line = "abcd";
    while (*line != '\0')
    putchar (toupper( (unsigned char)*line++ ));

    (The `(unsigned char)' cast guards against the possibility
    that negative-valued characters might appear in the string.
    In this particular example all the characters have positive
    values, but get in the habit of using the cast anyhow.)

    --
     
    Eric Sosman, Dec 10, 2004
    #8
  9. Eric Sosman <> wrote in
    news:cpcfdq$s0k$:

    >>>char* line = "abcd";

    >>
    >> Pointer mis-match, char *line should not point to a const char *
    >> "abcd". What if "abcd" is placed into non-writable memory?

    >
    > No mismatch. The literal creates an array of ordinary
    > `char', not `const'-qualified. True, that array cannot be
    > written safely, but its type is non-`const' anyhow.


    You're rigth, sadly. What an awful choice. I still find bugs like this
    where people assume a char * is writable (as one might expect) but where
    the pointer points to a string literal. Wouldn't it have been better to
    have string literals be of type const char *?

    --
    - Mark ->
    --
     
    Mark A. Odell, Dec 10, 2004
    #9
  10. CBFalconer <> writes:
    > Janice wrote:
    >>
    >> char* line = "abcd";
    >> How to convert the line to upper case and print?
    >> Any option for printf to do this?

    >
    > You can't and no. However if you had defined line as:
    >
    > char line[] = "abcd";
    >
    > you would have been able to convert it. Now you should spend some
    > time thinking about what the difference is. It is fundamental.


    That depends on whether "convert" means to convert it in-place, or to
    create a converted copy. The problem statement doesn't make this
    clear.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 10, 2004
    #10
  11. Janice

    Eric Sosman Guest

    Mark A. Odell wrote:
    > Eric Sosman <> wrote in
    > news:cpcfdq$s0k$:
    >
    >
    >>>>char* line = "abcd";
    >>>
    >>>Pointer mis-match, char *line should not point to a const char *
    >>>"abcd". What if "abcd" is placed into non-writable memory?

    >>
    >> No mismatch. The literal creates an array of ordinary
    >>`char', not `const'-qualified. True, that array cannot be
    >>written safely, but its type is non-`const' anyhow.

    >
    > You're rigth, sadly. What an awful choice. I still find bugs like this
    > where people assume a char * is writable (as one might expect) but where
    > the pointer points to a string literal. Wouldn't it have been better to
    > have string literals be of type const char *?


    According to the Rationale, string literals have this
    peculiar property to avoid breaking existing code:

    [...] string literals do not have the type /array
    of const char/ in order to avoid the problems of
    pointer type checking, particularly with library
    functions, since assigning a /pointer to const char/
    to a plain /pointer to char/ is not valid. [...]

    As an example of how `const' literals could break
    perfectly good existing code, consider this pre-C89 program:

    #include <stdio.h>

    greet(whom)
    char *whom;
    {
    printf ("Hello, %s!\n", whom);
    }

    int main() {
    greet ("world");
    return 0;
    }

    Note that greet() takes a plain `char*' argument, because
    a pre-C89 coder had no way to write a `const' qualifier: the
    keyword was added to the language (along with `void' and some
    other "new stuff") by the ANSI committee. Now, what would
    have happened if the committee had made string literals be
    `const char[]'? The call to greet() in main() would have
    become illegal, because you can't convert `const char*' to
    plain `char*' without a cast.

    Now multiply this trivial example by the twenty or so
    years' worth of C code in existence before the new Standard
    came along. If every string-accepting function in the entire
    corpus of existing code had suddenly started refusing to accept
    string literals as arguments, the new Standard might have had
    some slight difficulty in gaining acceptance ...

    Hindsight often tells us how things ought to have been
    done differently, but it's not always possible to undo them.

    The Clacking Keyboard writes: and having writ,
    Clacks on: nor all thy Prototypes nor Wit
    Shall rewind() it to fgets() half a Line,
    Nor all thy Tears re-Const a Char of it.

    --
     
    Eric Sosman, Dec 10, 2004
    #11
  12. Janice

    CBFalconer Guest

    "Mark A. Odell" wrote:
    > Eric Sosman <> wrote in
    >
    >>>> char* line = "abcd";
    >>>
    >>> Pointer mis-match, char *line should not point to a const char *
    >>> "abcd". What if "abcd" is placed into non-writable memory?

    >>
    >> No mismatch. The literal creates an array of ordinary
    >> `char', not `const'-qualified. True, that array cannot be
    >> written safely, but its type is non-`const' anyhow.

    >
    > You're rigth, sadly. What an awful choice. I still find bugs like
    > this where people assume a char * is writable (as one might expect)
    > but where the pointer points to a string literal. Wouldn't it have
    > been better to have string literals be of type const char *?


    Yes, except that by the time 'const' was added to the language
    (circa 1989) there were 15 or so years of previous practice that
    needed 'not breaking'.

    If you are using gcc you can get the effect with -Wwrite-strings.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Dec 10, 2004
    #12
  13. Janice

    pete Guest

    Keith Thompson wrote:
    >
    > CBFalconer <> writes:
    > > Janice wrote:
    > >>
    > >> char* line = "abcd";
    > >> How to convert the line to upper case and print?
    > >> Any option for printf to do this?

    > >
    > > You can't and no. However if you had defined line as:
    > >
    > > char line[] = "abcd";
    > >
    > > you would have been able to convert it. Now you should spend some
    > > time thinking about what the difference is. It is fundamental.

    >
    > That depends on whether "convert" means to convert it in-place, or to
    > create a converted copy. The problem statement doesn't make this
    > clear.


    It may mean to have the converted values
    written to the standard output stream.

    /* BEGIN new.c */

    #include <stdio.h>
    #include <ctype.h>

    int main(void)
    {
    char *line = "abcd";

    while(*line != '\0') {
    putchar(toupper(*line));
    ++line;
    }
    putchar('\n');
    return 0;
    }

    /* END new.c */

    --
    pete
     
    pete, Dec 11, 2004
    #13
  14. the Rationale, string literals, and const (was: lower case to upper case)

    Eric Sosman <> writes:
    > Mark A. Odell wrote:


    >> Wouldn't it have been better to have string literals be of type
    >> const char *?


    (Or even "array of const char".)

    > According to the Rationale, string literals have this peculiar
    > property to avoid breaking existing code


    [snippage]

    And this (almost useless, but certainly valid on a platform lacking
    "const" ... like, say, that the Rationale uses to justify non-const
    string literals) pre-C89 program is broken by that Standard:

    main() {
    char* const = "Hello, World!";
    puts(const);
    }

    The "avoid breaking existing code" argument is trotted out all the
    time in the Rationale, and it's bogus:

    - If there is no existing standard, then defining anything that
    conflicts with any existing usage anywhere will break existing code.
    C89 broke existing code.

    - If the new standard updates an old one, then defining anything other
    than previously-undefined areas will break existing code.
    C99 broke existing code.

    C89 made sting literals non-const, and C99 didn't fix it, which
    contributes to poor code now and in the future.

    But don't blame "existing code" for it.
    It's the fault of the Standard-setters alone.

    <steps off soapbox>

    mlp
     
    Mark L Pappin, Dec 11, 2004
    #14
  15. Re: the Rationale, string literals, and const (was: lower case to upper case)

    On Sat, 11 Dec 2004 15:50:54 +1000, Mark L Pappin wrote:

    > Eric Sosman <> writes:
    >> Mark A. Odell wrote:

    >
    >>> Wouldn't it have been better to have string literals be of type
    >>> const char *?

    >
    > (Or even "array of const char".)
    >
    >> According to the Rationale, string literals have this peculiar
    >> property to avoid breaking existing code

    >
    > [snippage]
    >
    > And this (almost useless, but certainly valid on a platform lacking
    > "const" ... like, say, that the Rationale uses to justify non-const
    > string literals) pre-C89 program is broken by that Standard:
    >
    > main() {
    > char* const = "Hello, World!";
    > puts(const);
    > }
    >
    > The "avoid breaking existing code" argument is trotted out all the
    > time in the Rationale, and it's bogus:


    It may be bogus in some circumstances but it is certainly not inherently
    bogus. Your example above is likely to affect a minority of programs, I
    don't recall a massive outcry about this, which there would have been if
    it broke a lot of code.

    Also consider that it would be fairly trivial to fix this automatically
    even for huge program sources: write a program that searches for the
    word "const" in the context of an identifier and changes it to a valid
    identifier that doesn't clash with others in the program.

    The only difficulty would be if the identifier const was used in non-local
    interface specifications e.g. in libraries.

    > - If there is no existing standard, then defining anything that
    > conflicts with any existing usage anywhere will break existing code.
    > C89 broke existing code.


    Yes, but there's a matter of degree. Something that affects odd bits of
    code here and there is not the same problem as something that affects
    nearly the whole body of existing code. The fact is that code such as

    char *str = "string";

    was the normal, correct, mainstream way of doing things pre-C89.

    Although there was no standards body ratified standard before C89, there
    was still K&R 1 which provided an effective baseline for all C compiler
    writers.

    > - If the new standard updates an old one, then defining anything other
    > than previously-undefined areas will break existing code.
    > C99 broke existing code.
    >
    > C89 made sting literals non-const, and C99 didn't fix it, which
    > contributes to poor code now and in the future.
    >
    > But don't blame "existing code" for it.
    > It's the fault of the Standard-setters alone.


    There is no way that the standard committee could have made this change,
    it breaks too much. C is if anything a pragmatic language, and one of its
    big assets is the amount of C code that is already out there.

    Lawrence
     
    Lawrence Kirby, Dec 13, 2004
    #15
  16. Janice

    Eric Sosman Guest

    Re: the Rationale, string literals, and const

    Mark L Pappin wrote:
    > Eric Sosman <> writes:
    >
    >>Mark A. Odell wrote:

    >
    >
    >>>Wouldn't it have been better to have string literals be of type
    >>>const char *?

    >
    >
    > (Or even "array of const char".)
    >
    >
    >>According to the Rationale, string literals have this peculiar
    >>property to avoid breaking existing code

    >
    > [snippage]
    >
    > And this (almost useless, but certainly valid on a platform lacking
    > "const" ... like, say, that the Rationale uses to justify non-const
    > string literals) pre-C89 program is broken by that Standard:
    >
    > main() {
    > char* const = "Hello, World!";
    > puts(const);
    > }


    Does this mean you think the ANSI committee should not
    have invented the `const' keyword at all?

    Or does this mean you can't distinguish between "some
    small amount of breakage" and "massive, overwhelming, universal
    bloodbath?"

    Rummage through any corpus of pre-Standard C -- early Unix
    distributions, for example -- and count the number of uses of
    `const' as an identifier. Then count the number of times a
    string literal is passed to a function expecting a `char*'.

    > The "avoid breaking existing code" argument is trotted out all the
    > time in the Rationale, and it's bogus:
    >
    > - If there is no existing standard, then defining anything that
    > conflicts with any existing usage anywhere will break existing code.
    > C89 broke existing code.


    Some amount of breakage was inevitable, since pre-Standard
    C implementations disagreed on the meaning attached to the
    same constructions. What value should sprintf() return? Some
    pre-C89 implementations returned a count, others returned a
    pointer. On a 32-bit system, what should be the value and
    type of 0x80000000? Some implementations produced a negative
    `int', others an `unsigned int'. Should `far' be a keyword?

    > - If the new standard updates an old one, then defining anything other
    > than previously-undefined areas will break existing code.
    > C99 broke existing code.


    It is conceivable that C99 broke existing code. Anybody
    who used `restrict' as an identifier is in for some effort.
    Anybody who expected `//*' to mean "slash, followed by start
    of comment" will be unpleasantly surprised. And so on.

    Question: How many instances of these and other breakages
    have you personally encountered (excluding uses specifically
    contrived after the fact to illustrate the change)? Have you
    actually encountered even one such instance of breakage?

    > C89 made sting literals non-const, and C99 didn't fix it, which
    > contributes to poor code now and in the future.
    >
    > But don't blame "existing code" for it.
    > It's the fault of the Standard-setters alone.


    "There is nothing more difficult to take in hand,
    more perilous to conduct, or more uncertain in its
    success than to take the lead in the introduction
    of a new order of things."
    -- Niccolò Macchiavelli, 1513

    "So down with them! So down with them!
    Reform's a hated ogress!
    So down with them! So down with them!
    Down with the Flowers of Progress!"
    -- W.S. Gilbert, 1893

    --
     
    Eric Sosman, Dec 13, 2004
    #16
  17. Janice

    Richard Bos Guest

    Eric Sosman <> wrote:

    > Hindsight often tells us how things ought to have been
    > done differently, but it's not always possible to undo them.
    >
    > The Clacking Keyboard writes: and having writ,
    > Clacks on: nor all thy Prototypes nor Wit
    > Shall rewind() it to fgets() half a Line,
    > Nor all thy Tears re-Const a Char of it.


    *Applause*

    Richard
     
    Richard Bos, Dec 14, 2004
    #17
  18. Janice

    Richard Bos Guest

    Re: the Rationale, string literals, and const

    Eric Sosman <> wrote:

    > Mark L Pappin wrote:
    > > - If the new standard updates an old one, then defining anything other
    > > than previously-undefined areas will break existing code.
    > > C99 broke existing code.

    >
    > It is conceivable that C99 broke existing code. Anybody
    > who used `restrict' as an identifier is in for some effort.


    *cough* inline. Worst trivial change in the C99 Standard, easily.
    There's no good reason for it to be included at all (Geez, it was 1999 -
    get an optimising compiler already!), and it meant that I had to change
    a habit I'd used in all my textfile-reading programs. Input/output files
    were called infile/outfile; filenames usually inname/outname; and line
    buffers (you guessed it) inline/outline. Ow.

    Richard
     
    Richard Bos, Dec 14, 2004
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    4
    Views:
    730
    Jürgen Exner
    Dec 7, 2004
  2. David
    Replies:
    10
    Views:
    808
    James Lothian
    May 7, 2004
  3. Pierre

    Manipulation of strings: upper/lower case

    Pierre, Jan 15, 2005, in forum: C Programming
    Replies:
    32
    Views:
    946
    Lawrence Kirby
    Jan 20, 2005
  4. penny
    Replies:
    28
    Views:
    3,039
    Charlton Wilbur
    Mar 10, 2008
  5. BlackHelicopter
    Replies:
    0
    Views:
    616
    BlackHelicopter
    Jan 31, 2013
Loading...

Share This Page