Trying to understand character arrays.

Discussion in 'C Programming' started by drM, Apr 3, 2006.

  1. drM

    drM Guest

    Could anyone please offer some advice:
    Trying to play with character arrays in C, the code below generates
    this error.
    Anyone see something wrong?
    thank you in advance.


    >>>>>>>>

    #include <stdio.h>

    void test(char s[]);
    char helloworld[11];

    int main () {
    printf("%s", test(helloworld)); // <----Invalid use of void
    expression
    return 0;
    }


    void test (char t[])
    {

    t[0]='H';
    t[1]='e';
    t[2]='l';
    t[3]='l';
    t[4]='o';
    t[5]=' ';
    t[6]='W';
    t[7]='o';
    t[8]='r';
    t[9]='l';
    t[10]='d';
    t[11]='\0';

    }

    >>>>>>>>>>
    drM, Apr 3, 2006
    #1
    1. Advertising

  2. drM

    Michael Mair Guest

    drM schrieb:
    > Could anyone please offer some advice:
    > Trying to play with character arrays in C, the code below generates
    > this error.
    > Anyone see something wrong?
    > thank you in advance.
    >
    >
    >
    > #include <stdio.h>
    >
    > void test(char s[]);
    > char helloworld[11];
    >
    > int main () {
    > printf("%s", test(helloworld)); // <----Invalid use of void
    > expression


    1) This nicely illustrates why you should not use // comments in
    usenet messages
    2) test()'s return type is void -- "nothing".
    Nothing cannot be assigned to "anything" (anything non-void).
    You can either change test() to
    char *test (char *s);
    or you have to do it in two steps:
    test(helloworld);
    printf("%s", helloworld);
    3) Note that you should output '\n' as last character in order
    to make sure that you see any output at all.
    > return 0;
    > }
    >
    >
    > void test (char t[])
    > {
    >
    > t[0]='H';
    > t[1]='e';
    > t[2]='l';
    > t[3]='l';
    > t[4]='o';
    > t[5]=' ';
    > t[6]='W';
    > t[7]='o';
    > t[8]='r';
    > t[9]='l';
    > t[10]='d';
    > t[11]='\0';
    >


    1) If you want to change test() to char *test(char*), then
    insert
    return &t[0];
    here
    2) There are also strcpy() and strncpy()...

    > }


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Apr 3, 2006
    #2
    1. Advertising

  3. drM wrote:
    >
    > Could anyone please offer some advice:
    > Trying to play with character arrays in C, the code below generates
    > this error.
    > Anyone see something wrong?

    [...]
    > void test(char s[]);
    > char helloworld[11];

    [...]
    > printf("%s", test(helloworld)); // <----Invalid use of void expression

    [...]

    Hint 1: What does the error say?
    Hint 2: What type does test() return, and how does that relate to (1)?
    Hint 3: Can the type answered in (2) be passed to a function?
    Hint 4: What does printf's "%s" expect?

    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Don't e-mail me at: <mailto:>
    Kenneth Brody, Apr 3, 2006
    #3
  4. drM

    drM Guest

    Have just started in C, so your reply is most welcome.

    "1) This nicely illustrates why you should not use // comments in
    usenet messages "....Point taken.
    drM, Apr 3, 2006
    #4
  5. drM opined:

    > Have just started in C, so your reply is most welcome.


    Whose reply? To what?

    >
    > "1) This nicely illustrates why you should not use // comments in
    > usenet messages "....Point taken.


    You should also make a point of quoting what and who you're replying
    to. Read the link in my sig, and all the links in it...

    --
    Parallel lines never meet, unless you bend one or both of them.

    <http://clc-wiki.net/wiki/Introduction_to_comp.lang.c>
    Vladimir S. Oka, Apr 3, 2006
    #5
  6. drM

    drM Guest

    2) test()'s return type is void -- "nothing".
    Nothing cannot be assigned to "anything" (anything non-void).
    You can either change test() to
    char *test (char *s);
    or you have to do it in two steps:
    test(helloworld);
    printf("%s", helloworld);


    Michael....If I understand you correctly, the type (void) is producing
    an error, not because of the (void) test(helloworld) function, but
    because of the printf function...or am I completely misunderstanding
    you.
    tks
    drM, Apr 3, 2006
    #6
  7. "drM" <> writes:
    > Have just started in C, so your reply is most welcome.
    >
    > "1) This nicely illustrates why you should not use // comments in
    > usenet messages "....Point taken.


    Please learn to quote properly. <http://cfaj.freeshell.org/google/>

    --
    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, Apr 3, 2006
    #7
  8. drM

    drM Guest

    Keith Thompson wrote:

    >
    > Please learn to quote properly. <http://cfaj.freeshell.org/google/>
    >



    Boy...this is a tough crowd!! :) Thanks for all the input.
    drM, Apr 3, 2006
    #8
  9. drM

    drM Guest

    Michael Mair wrote:

    > Nothing cannot be assigned to "anything" (anything non-void).
    > You can either change test() to
    > char *test (char *s);
    > or you have to do it in two steps:
    > test(helloworld);
    > printf("%s", helloworld);


    Michael....If I understand you correctly, the type (void) is producing
    an error, not because of the (void) test(helloworld) function, but
    because of the printf function...or am I completely misunderstanding
    you.
    tks
    drM, Apr 3, 2006
    #9
  10. "drM" <> writes:
    > Michael Mair wrote:
    >> Nothing cannot be assigned to "anything" (anything non-void).
    >> You can either change test() to
    >> char *test (char *s);
    >> or you have to do it in two steps:
    >> test(helloworld);
    >> printf("%s", helloworld);

    >
    > Michael....If I understand you correctly, the type (void) is producing
    > an error, not because of the (void) test(helloworld) function, but
    > because of the printf function...or am I completely misunderstanding
    > you.


    It's not really one or the other, it's the combination. Your test
    function was declared to return void; you tried to pass the
    (nonexistent) result of that function to printf. You called printf
    with a "%s" format, which means you need to pass it a char* as its
    second argument.

    If you had passed, say, an integer value:

    printf("%s", 42);

    then you would have been invoking undefined behavior. Since the types
    for the arguments to printf are determined by the value of the format
    string, they can't generally be checked by the compiler. But you
    can't pass a nonexistent value (the result of a void function) as an
    argument, so the compiler rejects the call.

    --
    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, Apr 3, 2006
    #10
  11. drM

    drM Guest


    > > Michael....If I understand you correctly, the type (void) is producing
    > > an error, not because of the (void) test(helloworld) function, but
    > > because of the printf function...or am I completely misunderstanding
    > > you.

    >


    Keith Thompson wrote:

    > It's not really one or the other, it's the combination. Your test
    > function was declared to return void; ...... you
    > can't pass a nonexistent value (the result of a void function) as an
    > argument, (to printf) so the compiler rejects the call.



    Thank you Keith, that clears it up for me and in fact helps me
    understand the issue better.

    Michael.
    drM, Apr 3, 2006
    #11
  12. drM

    Old Wolf Guest

    drM wrote:
    > Could anyone please offer some advice:


    There is another bug in this program:

    > char helloworld[11];
    >
    > void test (char t[])
    > {
    > t[0]='H';
    > t[1]='e';
    > t[2]='l';
    > t[3]='l';
    > t[4]='o';
    > t[5]=' ';
    > t[6]='W';
    > t[7]='o';
    > t[8]='r';
    > t[9]='l';
    > t[10]='d';
    > t[11]='\0';
    > }


    helloworld[] only has space for 11 characters, but you have
    written 12 characters to it. This is a buffer overflow.
    Old Wolf, Apr 3, 2006
    #12
  13. drM

    jaysome Guest

    Michael Mair wrote:

    > drM schrieb:
    >
    >> Could anyone please offer some advice:
    >> Trying to play with character arrays in C, the code below generates
    >> this error.
    >> Anyone see something wrong?
    >> thank you in advance.
    >>
    >>
    >>
    >> #include <stdio.h>
    >>
    >> void test(char s[]);
    >> char helloworld[11];
    >>
    >> int main () {
    >> printf("%s", test(helloworld)); // <----Invalid use of void
    >> expression

    >
    >
    > 1) This nicely illustrates why you should not use // comments in
    > usenet messages


    No. It illustrates why the de facto Usenet standards are broken in this
    day and age. After all:

    1. ISO/IEC 9899:1999(E) is dated 1999-12-01, which was over six years
    ago. That C standard--the current one--allows // comments. I recall that
    some regulars in here were overflowing with enthusiasm for some time
    before and after the ratification of that standard. If their enthusiasm
    is alive now as it was then, they should weigh in on this issue.

    2. C++ is a *BIG* part of Usenet and has always allowed // comments (as
    well as /* */ comments). Arguably, C++ programmers prefer to use //
    comments at least sometimes, if not most or all of the time. By your
    standards, should those C++ programmers revert to /* */ comments when
    posting to Usenet?

    I submit that other things related to Usenet are broken, not the current
    C and C++ standards. The days of 72 characters per line should be
    considered folklore--these days there is no reason whatsoever why line
    lengths cannot be significantly a lot more than that. I propose 132.
    YMMV, especially if you're using *NIX.

    --
    jay
    jaysome, Apr 4, 2006
    #13
  14. jaysome <> writes:
    > Michael Mair wrote:
    >> drM schrieb:

    [...]
    >>> int main () {
    >>> printf("%s", test(helloworld)); // <----Invalid use of void
    >>> expression

    >> 1) This nicely illustrates why you should not use // comments in
    >> usenet messages

    >
    > No. It illustrates why the de facto Usenet standards are broken in
    > this day and age. After all:
    >
    > 1. ISO/IEC 9899:1999(E) is dated 1999-12-01, which was over six years
    > ago. That C standard--the current one--allows // comments. I recall
    > that some regulars in here were overflowing with enthusiasm for some
    > time before and after the ratification of that standard. If their
    > enthusiasm is alive now as it was then, they should weigh in on this
    > issue.


    As you know, the C99 standard allows both // and /*...*/ comments.
    And, as you probably also know, there aren't as many C99 conforming
    compilers as we might like.

    > 2. C++ is a *BIG* part of Usenet and has always allowed // comments
    > (as well as /* */ comments). Arguably, C++ programmers prefer to use
    > // comments at least sometimes, if not most or all of the time. By
    > your standards, should those C++ programmers revert to /* */ comments
    > when posting to Usenet?


    I don't know. Perhaps you should ask in comp.lang.c++.

    > I submit that other things related to Usenet are broken, not the
    > current C and C++ standards. The days of 72 characters per line should
    > be considered folklore--these days there is no reason whatsoever why
    > line lengths cannot be significantly a lot more than that. I propose
    > 132. YMMV, especially if you're using *NIX.


    I read Usenet in an 80-column window. I could make it 132 columns if
    I wanted to, but I find text composed of lines limited to 80 columns
    or so easier to read. I note that you used no more than 70 columns
    per line yourself.

    Do you expect to get a change like this to be adopted by each of the
    thousands of existing newsgroups?

    But the point you're ignoring is that, since a long line was wrapped
    some time after it was posted, the comment was split and a syntax
    error was introduced. If a /*...*/ comment had been used instead,
    this would have been less of a problem.

    Personally, I like end-of-line comments better than classic C-style
    comments, but there are valid reasons for using avoiding them on
    Usenet.

    --
    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, Apr 4, 2006
    #14
  15. drM

    CBFalconer Guest

    jaysome wrote:
    > Michael Mair wrote:
    >

    .... snip ...
    >>
    >> 1) This nicely illustrates why you should not use // comments in
    >> usenet messages

    >
    > No. It illustrates why the de facto Usenet standards are broken in
    > this day and age. After all:
    >

    .... snip ...
    >
    > I submit that other things related to Usenet are broken, not the
    > current C and C++ standards. The days of 72 characters per line
    > should be considered folklore--these days there is no reason
    > whatsoever why line lengths cannot be significantly a lot more
    > than that. I propose 132. YMMV, especially if you're using *NIX.


    And you would be dead wrong, for multiple reasons. First, long
    lines are hard to read. 80 characters is already taxing. That is
    why sane documents limit lines to 65 or so characters, and
    newspapers split their text into columns.

    Much software has grown up around the 72 and 80 char limits. It
    works. There is no need to discard this.

    This software includes the usenet system, and the majority of text
    windows on almost any system today. Funnily wrapped lines, and
    lines that are offscreen, are especially hard to read.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Also see <http://www.safalra.com/special/googlegroupsreply/>
    CBFalconer, Apr 4, 2006
    #15
  16. drM

    Michael Mair Guest

    jaysome schrieb:
    > Michael Mair wrote:
    >> drM schrieb:
    >>
    >>> Could anyone please offer some advice:
    >>> Trying to play with character arrays in C, the code below generates
    >>> this error.
    >>> Anyone see something wrong?
    >>> thank you in advance.
    >>>
    >>> #include <stdio.h>
    >>>
    >>> void test(char s[]);
    >>> char helloworld[11];
    >>>
    >>> int main () {
    >>> printf("%s", test(helloworld)); // <----Invalid use of void
    >>> expression

    >>
    >> 1) This nicely illustrates why you should not use // comments in
    >> usenet messages

    >
    > No. It illustrates why the de facto Usenet standards are broken in this
    > day and age. After all:
    >
    > 1. ISO/IEC 9899:1999(E) is dated 1999-12-01, which was over six years
    > ago. That C standard--the current one--allows // comments. I recall that
    > some regulars in here were overflowing with enthusiasm for some time
    > before and after the ratification of that standard. If their enthusiasm
    > is alive now as it was then, they should weigh in on this issue.
    >
    > 2. C++ is a *BIG* part of Usenet and has always allowed // comments (as
    > well as /* */ comments). Arguably, C++ programmers prefer to use //
    > comments at least sometimes, if not most or all of the time. By your
    > standards, should those C++ programmers revert to /* */ comments when
    > posting to Usenet?
    >
    > I submit that other things related to Usenet are broken, not the current
    > C and C++ standards. The days of 72 characters per line should be
    > considered folklore--these days there is no reason whatsoever why line
    > lengths cannot be significantly a lot more than that. I propose 132.
    > YMMV, especially if you're using *NIX.


    This may or may not be true -- however, the line did not break at
    quoting but was broken in the OP. I have seen people shooting
    themselves in the foot with the difference between "//.... \"
    and "//.... \ ".
    BTW: Even in C++, I use BCPL line comments only at the beginning
    of a line and not preceded by code.

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Apr 4, 2006
    #16
  17. jaysome <> skriver:

    > C and C++ standards. The days of 72 characters per line should be
    > considered folklore--these days there is no reason whatsoever why line
    > lengths cannot be significantly a lot more than that. I propose 132.
    > YMMV, especially if you're using *NIX.


    At 132 charaters a side by side diff is 265 charaters wide at least.
    There are few screens that can display that is a resonabe font. Also
    that long lines are hard to compare and see what charater differs. 80
    and 160 wide screens works, but already three it stats to get harder
    to read and work efficently.

    If the magicasl number is 72, 65, 80 or 95 i can't say. 132 is to
    much, i think 60 is to little. Sometimes i run uptowards 130 but those
    lines always comes back hunting me later when that don't work.

    / Anders
    --
    http://anders.arnholm.nu/ Keep on Balping
    Anders Arnholm, Apr 4, 2006
    #17
  18. drM

    John Bode Guest

    drM wrote:
    > Could anyone please offer some advice:
    > Trying to play with character arrays in C, the code below generates
    > this error.
    > Anyone see something wrong?
    > thank you in advance.
    >
    >
    > >>>>>>>>

    > #include <stdio.h>
    >
    > void test(char s[]);


    When you pass an array as an argument to a function, what actually gets
    passed is a pointer to the first element of the array; the above
    prototype is a synonym for

    void test(char *s);

    Because of how array subscripting is defined, you can still access
    individual elements of s as s[0], s[1], etc., but the *type* of s is
    "pointer to char", not "array of char". This has nothing to do with
    your specific error, but it's something that I guarantee is going to
    trip you up soon.

    > char helloworld[11];


    Remember that when you declare an N-element array, the array subscripts
    run from 0 to N-1; in this case, you've declared helloworld to hold 11
    characters, which means the you can access elements from 0 to 10.
    However, in your test function below, you try to write to elements 0 to
    11. Writing to that last element writes beyond the end of the array,
    which leads to undefined behavior. Change this declaration so that
    helloworld contains 12 elements.

    There's no good reason to declare helloworld at file scope (i.e., as a
    global variable). As a general rule, you want to limit the scope of
    variables as much as possible to avoid maintenance headaches. Since
    you're passing it as an argument to test, there's no reason to have it
    globally visible to both main() and test(). Move the declaration so
    that it's within main.

    >
    > int main () {
    > printf("%s", test(helloworld)); // <----Invalid use of void


    Okay, here's the actual problem. The "%s" conversion specifier expects
    an argument of type "char *"; however, you've defined test() to return
    void (I'm pretty sure that printf() doesn't like *any* of its arguments
    to be void, which is why you get a compile-time diagnostic; how do you
    format an expression that has no value?). There are two ways around
    this:

    1. Change the return type of test to char *, and return the value of
    the input parameter (it's a good idea for the parameter names in the
    function declaration match those in the function definition, btw; makes
    life easier for other people reading the code):

    char *test(char *t)
    {
    /* copy "Hello World" to t */
    return t;
    }

    2. Leave the return type as it is, call test() before calling
    printf(), and pass the modified helloworld as the argument to printf(),
    like so:

    test(helloworld);
    printf("%s\n", helloworld);

    Note: because of how C I/O works, if you don't have printf() emit a
    newline, the text may not be flushed to output immediately, and it will
    look like your program isn't doing anything. So you either need a
    newline in the control string, as I've done above, or if you don't want
    a newline at that point, you should add the line

    fflush(stdout);

    after the printf() statement.

    > expression
    > return 0;
    > }
    >
    >
    > void test (char t[])
    > {
    >
    > t[0]='H';
    > t[1]='e';
    > t[2]='l';
    > t[3]='l';
    > t[4]='o';
    > t[5]=' ';
    > t[6]='W';
    > t[7]='o';
    > t[8]='r';
    > t[9]='l';
    > t[10]='d';
    > t[11]='\0';
    >


    There's a library function that allows you to do this with much less
    pain:

    strcpy(t, "Hello, World");

    (be sure to #include <string.h>).
    John Bode, Apr 4, 2006
    #18
  19. drM

    drM Guest

    John Bode wrote:

    > When you pass an array as an argument to a function, what actually gets
    > passed is a pointer to the first element of the array; the above
    > prototype is a synonym for......................
    >
    >


    John,
    thank you for that explanation. I am slowly working my way through K&R,
    and with some help, it is actually turning out to be a lot of fun.
    drM, Apr 4, 2006
    #19
  20. drM

    Default User Guest

    CBFalconer wrote:

    > jaysome wrote:
    > > Michael Mair wrote:
    > >

    > ... snip ...
    > > >
    > >> 1) This nicely illustrates why you should not use // comments in
    > >> usenet messages

    > >
    > > No. It illustrates why the de facto Usenet standards are broken in
    > > this day and age. After all:
    > >

    > ... snip ...
    > >
    > > I submit that other things related to Usenet are broken, not the
    > > current C and C++ standards. The days of 72 characters per line
    > > should be considered folklore--these days there is no reason
    > > whatsoever why line lengths cannot be significantly a lot more
    > > than that. I propose 132. YMMV, especially if you're using *NIX.

    >
    > And you would be dead wrong, for multiple reasons. First, long
    > lines are hard to read. 80 characters is already taxing. That is
    > why sane documents limit lines to 65 or so characters, and
    > newspapers split their text into columns.


    I definitely agree. While XanaNews in the size window I use can display
    lines much longer than that without wrapping, it causes a lot more eye
    movement and therefore strain. Narrower == gooder. Or sumpin.



    Brian
    Default User, Apr 4, 2006
    #20
    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. Paul K

    Trying to understand...

    Paul K, Nov 19, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    340
    Paul K
    Nov 19, 2003
  2. =?Utf-8?B?QmlsbCBCb3Jn?=

    Trying to understand ticket/cookie expiration

    =?Utf-8?B?QmlsbCBCb3Jn?=, Oct 8, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    352
    =?Utf-8?B?QmlsbCBCb3Jn?=
    Oct 8, 2004
  3. jim

    trying to understand postback

    jim, Nov 22, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    364
    =?Utf-8?B?Sm9lbCBDYWRl?=
    Nov 22, 2004
  4. Philipp
    Replies:
    21
    Views:
    1,109
    Philipp
    Jan 20, 2009
  5. Sherm Pendley
    Replies:
    8
    Views:
    119
    Tad McClellan
    Jun 24, 2005
Loading...

Share This Page