printing first char

Discussion in 'C Programming' started by Bill Cunningham, Jun 22, 2013.

  1. I have tried several things and always get a seg fault. What I want to
    do is just print out the first char of an array. Here's my latest attempt.
    Maybe someone knows what I'm trying to do.

    #include <stdio.h>

    int main()
    {
    char a[] = "+hello world\n";
    printf("%s\n", a[0]);
    return 0;
    }
    Bill Cunningham, Jun 22, 2013
    #1
    1. Advertising

  2. Bill Cunningham

    Lanarcam Guest

    Le 22/06/2013 13:09, Bill Cunningham a écrit :
    > I have tried several things and always get a seg fault. What I want to
    > do is just print out the first char of an array. Here's my latest attempt.
    > Maybe someone knows what I'm trying to do.
    >
    > #include <stdio.h>
    >
    > int main()
    > {
    > char a[] = "+hello world\n";
    > printf("%s\n", a[0]);
    > return 0;
    > }
    >
    >

    You should write

    printf("%c\n", a[0]);

    You want to print a char (%c) not a string (%s).
    Lanarcam, Jun 22, 2013
    #2
    1. Advertising

  3. Lanarcam wrote:

    > You should write
    >
    > printf("%c\n", a[0]);
    >
    > You want to print a char (%c) not a string (%s).


    Oh ok. Sounds simple enough. Thanks
    Bill Cunningham, Jun 22, 2013
    #3
  4. Bill Cunningham

    Jorgen Grahn Guest

    On Sat, 2013-06-22, Bill Cunningham wrote:
    > I have tried several things and always get a seg fault. What I want to
    > do is just print out the first char of an array. Here's my latest attempt.
    > Maybe someone knows what I'm trying to do.


    It's better if you tell us, unless it's a riddle.

    > #include <stdio.h>
    >
    > int main()
    > {
    > char a[] = "+hello world\n";
    > printf("%s\n", a[0]);
    > return 0;
    > }


    You should ask your compiler to report more warnings. Mine tells me:

    foo.c:6:5: warning: format '%s' expects argument of type 'char *', but
    argument 2 has type 'int'

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Jun 22, 2013
    #4
  5. Lanarcam <> wrote:

    (sniop)

    > You should write


    > printf("%c\n", a[0]);


    > You want to print a char (%c) not a string (%s).


    Or if you really want %s, then:

    printf("%.1s\n",a);

    To print the nth character of a, (where n starts at 0)

    printf("%.1s\n",a+n);

    -- glen
    glen herrmannsfeldt, Jun 22, 2013
    #5
  6. On Saturday, June 22, 2013 1:51:31 PM UTC+1, Jorgen Grahn wrote:
    > On Sat, 2013-06-22, Bill Cunningham wrote:
    >
    >
    > foo.c:6:5: warning: format '%s' expects argument of type 'char *', but
    >
    > argument 2 has type 'int'
    >

    What a clever compiler. Mine tells me that printf() is unsafe and tries
    to force me to use the wide version, which has no support for floating
    point.
    Malcolm McLean, Jun 22, 2013
    #6
  7. Bill Cunningham

    Ian Collins Guest

    Malcolm McLean wrote:
    > On Saturday, June 22, 2013 1:51:31 PM UTC+1, Jorgen Grahn wrote:
    >> On Sat, 2013-06-22, Bill Cunningham wrote:
    >>
    >>
    >> foo.c:6:5: warning: format '%s' expects argument of type 'char *', but
    >>
    >> argument 2 has type 'int'
    >>

    > What a clever compiler. Mine tells me that printf() is unsafe and tries
    > to force me to use the wide version, which has no support for floating
    > point.


    Always have more than one tool in your box!

    One of the good features of code derived from OpenSolaris is it has to
    compile cleanly with Sun's compiler+lint and gcc.

    --
    Ian Collins
    Ian Collins, Jun 23, 2013
    #7
  8. Bill Cunningham

    Xavier Roche Guest

    You might consider minor changes in your code,

    Le 23/06/2013 22:23, paskali a écrit :
    > char *str = "+string+\n";


    const char* str = "+string+\n";
    (the string is not writable, so this is safer to tell the compiler)

    > int idx = 0;


    size_t idx = 0;
    (the canonical integer to be used as offset in memory is size_t)

    > do {


    for(idx = 0 ; str[idx] != '\0' ; idx++) {
    (a for-loop is safer is the string is empty, and comparing a character
    with the terminating character is better than comparing it with the NULL
    pointer)

    ie.:
    int main(void) {
    const char *str = "+string+\n";
    size_t idx;

    for(idx = 0 ; str[idx] != '\0' ; idx++) {
    printf("%c", str[idx]);
    }
    ....
    }
    Xavier Roche, Jun 23, 2013
    #8
  9. On 6/22/2013 7:09 AM, Bill Cunningham wrote:
    > I have tried several things and always get a seg fault. What I want to
    > do is just print out the first char of an array. Here's my latest attempt.
    > Maybe someone knows what I'm trying to do.


    Use the correct printf specifier:
    >
    > #include <stdio.h>
    >
    > int main()
    > {
    > char a[] = "+hello world\n";
    > printf("%s\n", a[0]);

    ^
    c
    > return 0;
    > }
    >
    >
    Martin Ambuhl, Jun 24, 2013
    #9
  10. On Sun, 23 Jun 2013 20:23:55 GMT, "paskali" <>
    wrote:

    >Bill Cunningham <> wrote:
    >
    >> I have tried several things and always get a seg fault. What I want to
    >> do is just print out the first char of an array. Here's my latest attempt.
    >> Maybe someone knows what I'm trying to do.
    >>
    >> #include <stdio.h>
    >>
    >> int main()
    >> {
    >> char a[] = "+hello world\n";
    >> printf("%s\n", a[0]);
    >> return 0;
    >> }
    >>

    >
    >As well as some one more expert has written you have to replace
    >printf("%s\n", a[0]) with printf("%c\n", a[0]).
    >
    >However, some time i have found more confortable to print the entire
    >string as following:


    The original post did not ask about printing anything other than a
    single character.

    >#include <stdio.h>
    >
    >int main(void) {
    >
    > char *str = "+string+\n";
    > int idx = 0;
    >
    > do {
    > printf("%c", str[idx++]);
    > } while(str[idx] != NULL);


    This will fail on those systems which define NULL as (void*)0.

    Why would you want to call printf multiple times? What is the benefit
    since you assume str is a properly terminated string?

    >}
    >
    >May be some one dislike that but for me is good.


    --
    Remove del for email
    Barry Schwarz, Jun 24, 2013
    #10
  11. Bill Cunningham

    Ian Collins Guest

    Barry Schwarz wrote:
    > On Sun, 23 Jun 2013 20:23:55 GMT, "paskali" <>
    > wrote:


    There be tolls in these parts.


    --
    Ian Collins
    Ian Collins, Jun 24, 2013
    #11
  12. On 23-Jun-13 16:01, paskali wrote:
    > Xavier Roche <> wrote:
    >
    >>> int idx = 0;

    >>
    >> size_t idx = 0;
    >> (the canonical integer to be used as offset in memory is size_t)
    >>

    >
    > Usually there are not differents (in bytes) between short and int,
    > else i would to prefer (and it would to have logically more sense):
    >
    > unsigned short idx = 0;


    There is no guarantee that short and int are the same size, and on most
    common systems today they are certainly different (16-bit short, 32-bit
    int).

    Of course, for this particular program, unsigned (or even signed) char
    would work just as well since the string is hardcoded and known to be
    rather short.

    >>> do {

    >>
    >> for(idx = 0 ; str[idx] != '\0' ; idx++) {
    >> (a for-loop is safer is the string is empty, and comparing a
    >> character with the terminating character is better than comparing
    >> it with the NULL pointer)

    >
    > In this case, for me, there are not differences, of course that you
    > wrote is good, too!


    It's poor practice to test your data for validity _after_ using it. A
    while loop is just as simple as a do-while loop, yet it does not suffer
    the same defect. I've never found a valid use for do-while loops other
    than the macro hack.

    Again, in this particular case it doesn't matter since the string is
    hardcoded and known to be at least one character long, but defensive
    coding is a good habit to practice.

    printf("%c", ...) is severe overkill compared to putchar(). True, a
    decent compiler may substitute the latter for you when appropriate, but
    why write something that is _more_ complicated than required? (Plus,
    putchar() is a macro, which implies it'll be faster than printf(),
    though the Standard doesn't guarantee that.)

    IMHO, while loops are more natural with an iterator, which is the
    simpler and more idiomatic construct for sequentially traversing a string:

    char *s = str;
    while (*s) {
    putchar(*s++);
    }

    but for loops are more natural with indexes:

    size_t idx;
    for (idx=str; !str[idx]; idx++) {
    putchar(str[idx]);
    }

    That's a matter of style, though; either combination can work.

    > missing on my code is the *always* present "return 0"


    It's implied with C99 and later. In C89, which you seem to be obsessed
    with, your code is incorrect without an explicit return.

    S

    --
    Stephen Sprunk "God does not play dice." --Albert Einstein
    CCIE #3723 "God is an inveterate gambler, and He throws the
    K5SSS dice at every possible opportunity." --Stephen Hawking
    Stephen Sprunk, Jun 24, 2013
    #12
  13. On 24-Jun-13 00:21, Stephen Sprunk wrote:
    > for (idx=str; !str[idx]; idx++) {


    That should be:

    > for (idx=0; !str[idx]; idx++) {


    Argh.

    S

    --
    Stephen Sprunk "God does not play dice." --Albert Einstein
    CCIE #3723 "God is an inveterate gambler, and He throws the
    K5SSS dice at every possible opportunity." --Stephen Hawking
    Stephen Sprunk, Jun 24, 2013
    #13
  14. On 22-Jun-13 18:07, Ian Collins wrote:
    > Malcolm McLean wrote:
    >> On Saturday, June 22, 2013 1:51:31 PM UTC+1, Jorgen Grahn wrote:
    >>> foo.c:6:5: warning: format '%s' expects argument of type 'char
    >>> *', but argument 2 has type 'int'

    >>
    >> What a clever compiler.


    GCC has done that for a long time, using clever extensions and a bit of
    manipulation of your standard headers. You can even apply the same to
    your own functions that use printf()-style format strings, if you're
    willing to sacrifice portability (or simplicity, by adding #ifdefs).

    >> Mine tells me that printf() is unsafe and tries to force me to use
    >> the wide version,


    How odd; printf() is perfectly safe. I rarely use the wide versions
    since I almost always use UTF-8, which was specifically designed to work
    (nearly) transparently with non-wide code.

    >> which has no support for floating point.


    What? Why not?

    > Always have more than one tool in your box!
    >
    > One of the good features of code derived from OpenSolaris is it has
    > to compile cleanly with Sun's compiler+lint and gcc.


    Many open-source projects have similar rules (but for GCC only); if not,
    patches will usually appear shortly after someone else commits code that
    triggers a warning.

    Many folks compile with -Werror (or equivalent) by default because
    warnings usually indicate bugs. If a warning is spurious, we modify the
    code to avoid it rather than turn down the warning level.

    S

    --
    Stephen Sprunk "God does not play dice." --Albert Einstein
    CCIE #3723 "God is an inveterate gambler, and He throws the
    K5SSS dice at every possible opportunity." --Stephen Hawking
    Stephen Sprunk, Jun 24, 2013
    #14
  15. In article <>,
    Ian Collins <> wrote:
    >Barry Schwarz wrote:
    >> On Sun, 23 Jun 2013 20:23:55 GMT, "paskali" <>
    >> wrote:

    >
    >There be tolls in these parts.


    Ask not for whom the bell tolls...

    --
    Given Bush and his insanely expensive wars (*), that we will be paying for
    for generations to come, the only possible response a sensible person need
    ever give, when a GOPer/TeaBagger says anything about "deficits", is a
    polite snicker.

    (*) Obvious money transfers between the taxpayers and Bush's moneyed
    interests. Someday, we'll actually figure out a way to have a war where the
    money just gets moved around and nobody (on either side) gets injured or
    killed. That will be an accomplishment of which we will be justly proud.
    Kenny McCormack, Jun 24, 2013
    #15
  16. "paskali" <> writes:
    > Bill Cunningham <> wrote:
    >> I have tried several things and always get a seg fault. What I want to
    >> do is just print out the first char of an array. Here's my latest attempt.
    >> Maybe someone knows what I'm trying to do.
    >>
    >> #include <stdio.h>
    >>
    >> int main()
    >> {
    >> char a[] = "+hello world\n";
    >> printf("%s\n", a[0]);
    >> return 0;
    >> }
    >>

    >
    > As well as some one more expert has written you have to replace
    > printf("%s\n", a[0]) with printf("%c\n", a[0]).
    >
    > However, some time i have found more confortable to print the entire
    > string as following:


    He didn't ask about printing the entire string; he asked about printing
    just the first character. Why are you answering a question he didn't
    ask?

    > #include <stdio.h>
    >
    > int main(void) {
    >
    > char *str = "+string+\n";
    > int idx = 0;
    >
    > do {
    > printf("%c", str[idx++]);
    > } while(str[idx] != NULL);
    >
    > }
    >
    > May be some one dislike that but for me is good.


    NULL is (a macro that expands to) a null *pointer* constant. It doesn't
    make much sense to compare a char value to NULL. (It's likely that it
    will happen to work, but it's still poor style.) Use '\0' instead.

    Using a do-while loop rather than a while loop means you'll always print
    at least one character; for an empty string, you'll print the '\0'
    character, which is *probably* harmless if you happen to be printing to
    a terminal.

    If, unlike the OP, you wanted to print an entire string, it would be
    silly to use an explicit loop; just call printf with a "%s" format or
    use fputs().

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 24, 2013
    #16
  17. Stephen Sprunk <> writes:
    > On 22-Jun-13 18:07, Ian Collins wrote:
    >> Malcolm McLean wrote:
    >>> On Saturday, June 22, 2013 1:51:31 PM UTC+1, Jorgen Grahn wrote:
    >>>> foo.c:6:5: warning: format '%s' expects argument of type 'char
    >>>> *', but argument 2 has type 'int'
    >>>
    >>> What a clever compiler.

    >
    > GCC has done that for a long time, using clever extensions and a bit of
    > manipulation of your standard headers. You can even apply the same to
    > your own functions that use printf()-style format strings, if you're
    > willing to sacrifice portability (or simplicity, by adding #ifdefs).
    >
    >>> Mine tells me that printf() is unsafe and tries to force me to use
    >>> the wide version,

    >
    > How odd; printf() is perfectly safe. I rarely use the wide versions
    > since I almost always use UTF-8, which was specifically designed to work
    > (nearly) transparently with non-wide code.


    printf() isn't *perfectly* safe; it's very easy to misuse it in ways
    that result in undefined behavior. But it's absolutely standard, and
    can be used safely if you're careful. I'd be suspicious of any compiler
    (*cough* Microsoft) that advised me to use a less portable alternative.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 24, 2013
    #17
  18. Bill Cunningham

    James Kuyper Guest

    On 06/24/2013 11:57 AM, Keith Thompson wrote:
    ....
    > printf() isn't *perfectly* safe; it's very easy to misuse it in ways
    > that result in undefined behavior. But it's absolutely standard, and
    > can be used safely if you're careful. I'd be suspicious of any compiler
    > (*cough* Microsoft) that advised me to use a less portable alternative.


    My understanding is that printf_s() (K.3.5.3.3), which is new in C2011,
    is essentially the same as the "safer" alternative that the Microsoft
    compiler wants you to consider. It has certain associated run-time
    constraints: the format string must not be null, the %n specifier shall
    not appear in the format string, and any argument corresponding to a %s
    in the format string shall not be null. If any of these constraints are
    violated, printf_s() is guaranteed to return a negative number, which
    appears to be the sense in which it is considered to be safer.
    James Kuyper, Jun 24, 2013
    #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. wwj
    Replies:
    7
    Views:
    536
  2. wwj
    Replies:
    24
    Views:
    2,473
    Mike Wahler
    Nov 7, 2003
  3. Ben Pfaff
    Replies:
    5
    Views:
    458
    Tristan Miller
    Jan 17, 2004
  4. Steffen Fiksdal

    void*, char*, unsigned char*, signed char*

    Steffen Fiksdal, May 8, 2005, in forum: C Programming
    Replies:
    1
    Views:
    568
    Jack Klein
    May 9, 2005
  5. lovecreatesbeauty
    Replies:
    1
    Views:
    1,002
    Ian Collins
    May 9, 2006
Loading...

Share This Page