Thread: printf turns pointer into type int when %s expects type char

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    182

    printf turns pointer into type int when %s expects type char

    I think the code and error is self-explanatory. Why is this problem arising? Intuitively speaking, I think it has something to do with using pointer arrays instead of regular pointers. Other than that I'm lost!

    Code and compiler output below

    Code:
    root[~]# cc -Wall -pedantic 8.11.c
    8.11.c: In function 'main':
    8.11.c:32: warning: format '%s' expects type 'char *', but argument 2 has type 'int'
    8.11.c:32: warning: format '%s' expects type 'char *', but argument 3 has type 'int'
    8.11.c:32: warning: format '%s' expects type 'char *', but argument 4 has type 'int'
    8.11.c:32: warning: format '%s' expects type 'char *', but argument 5 has type 'int'
    8.11.c:32: warning: format '%s' expects type 'char *', but argument 6 has type 'int'
    8.11.c:32: warning: format '%s' expects type 'char *', but argument 7 has type 'int'
    
    root[~]# ./a.out
    Segmentation fault


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    int main()
    {
      char *article[ 5 ] = { "the", "a", "one", "some", "any" };
      char *noun[ 5 ] = { "boy", "girl", "dog", "town", "car" };
      char *verb[ 5 ] = { "drove", "jumped", "ran", "walked", "skipped" };
      char *preposition[ 5 ] = { "to", "from", "over", "under", "on" };
    
      srand( time( NULL ) );
      printf( "%s %s %s %s %s %s\n", 
              *article[ rand() % 5 + 1 ],
              *noun[ rand() % 5 + 1 ],
              *verb[ rand() % 5 + 1 ],
              *preposition[ rand() % 5 + 1 ],
              *article[ rand() % 5 + 1 ],
              *noun[ rand() % 5 + 1 ] );
    
      return 0;
    }

  2. #2
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Try removing the stars:
    Code:
      printf( "%s %s %s %s %s %s\n", 
              article[ rand() % 5 + 1 ],
              noun[ rand() % 5 + 1 ],
              verb[ rand() % 5 + 1 ],
              preposition[ rand() % 5 + 1 ],
              article[ rand() % 5 + 1 ],
              noun[ rand() % 5 + 1 ] );

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    182
    Thanks that did the trick.

    I have some questions.
    1) Don't pointers need to be dereferenced to work? I'm guessing that using array syntax already implies it's a dereferenced pointer but it's confusing nonetheless.

    2) Why did the compiler choose to turn the type char values into type int in this instance?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    1) Don't pointers need to be dereferenced to work? I'm guessing that using array syntax already implies it's a dereferenced pointer but it's confusing nonetheless.
    If a is an array or a pointer to the first element of an array, then a[n] is equivalent to *(a + n). (a[n] is also equivalent to n[a], but I find that potentially misleading.)
    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

  5. #5
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    A good read to help explain this. And this link is scattered all over this forum:

    http://www.c-faq.com/

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by yougene View Post
    1) Don't pointers need to be dereferenced to work? I'm guessing that using array syntax already implies it's a dereferenced pointer but it's confusing nonetheless.
    Yes, they do, but you misunderstand.
    Printf wants a pointer to the string because it does not want one character, it wants it all. That's why it takes a pointer.
    char* [] is also the same as char** when passed to a function.
    And when using [] on an array, you automatically dereference it.
    Code:
    char mystr[] = "My string";
    mystr[5]; /* == *(mystr + 5) */
    In other words, you are dereferencing it!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    Quote Originally Posted by laserlight View Post
    If a is an array or a pointer to the first element of an array, then a[n] is equivalent to *(a + n). (a[n] is also equivalent to n[a], but I find that potentially misleading.)
    Funny I recently was reading on how you could use n[a] or even n + a. Though anyone coding in such obfuscated style would not find much work.

  8. #8
    Registered User
    Join Date
    May 2006
    Posts
    182
    Quote Originally Posted by Elysia View Post
    Yes, they do, but you misunderstand.
    Printf wants a pointer to the string because it does not want one character, it wants it all. That's why it takes a pointer.
    So %s is actually looking for a referenced pointer address? It dereferences itself?

    char* [] is also the same as char** when passed to a function.
    And when using [] on an array, you automatically dereference it.
    That's what is confusing me. I thought the [ ] dereference one of the stars, so I thought I need to add another * to dereference the second pointer( I don't know if that's the correct way of saying it )

  9. #9
    Registered User
    Join Date
    May 2006
    Posts
    182
    Quote Originally Posted by laserlight View Post
    If a is an array or a pointer to the first element of an array, then a[n] is equivalent to *(a + n). (a[n] is also equivalent to n[a], but I find that potentially misleading.)
    Would n[ a ] be considered good programming? I can see some situations where this might be useful.


    Quote Originally Posted by slingerland3g View Post
    A good read to help explain this. And this link is scattered all over this forum:

    http://www.c-faq.com/
    Thanks for the link. It's going in my browser toolbar.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by yougene View Post
    So %s is actually looking for a referenced pointer address? It dereferences itself?
    No, it simply expects a pointer. An array can only be passed via a pointer and it expects an array.

    That's what is confusing me. I thought the [ ] dereference one of the stars, so I thought I need to add another * to dereference the second pointer( I don't know if that's the correct way of saying it )
    It dereferences one level, not two.
    But you thought wrong in that you needed to dereference twice. It wants an array, a pointer, not a char.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    May 2006
    Posts
    182
    >>Elysia
    Crystal clear, thank you

    It's like if dealing with a regulary array &#37;s would expect string not string[ someNumber ].

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yep.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    Quote Originally Posted by yougene View Post
    Would n[ a ] be considered good programming? I can see some situations where this might be useful.
    As far as the compiler is concerned and n is not an expression, it is the same thing as a[ n ]. I would really like to see the situations where you think it might be useful, as it generally is an obfuscating C idiom.
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  14. #14
    Registered User
    Join Date
    May 2006
    Posts
    182
    Quote Originally Posted by xuftugulus View Post
    As far as the compiler is concerned and n is not an expression, it is the same thing as a[ n ]. I would really like to see the situations where you think it might be useful, as it generally is an obfuscating C idiom.
    I was thinking it might be useful in a situation where you want to simply increment the name which in this case would be the number n. But on second though it's not very useful since there is still no easy way to increment a. Without a double pointer or something.

  15. #15
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I was thinking it might be useful in a situation [...]
    I have yet to see or hear about a situation outside of the IOCCC where it's viable, much less useful. The scary part is that most descriptions of subscripting will talk about this trick like it's some sort of amazing feature of C. I suppose when people run out of interesting things to say, they fall back on trivia.

    However, a similar trick actually is useful, and that's using a string literal as the object for subscripting:
    Code:
    #include <stdio.h>
    
    int main ( void )
    {
      int i;
    
      for ( i = 0; i < 10; i++ )
        putchar ( "0123456789"[i] );
    
      return 0;
    }
    >As far as the compiler is concerned and n is not an expression, it is the same thing as a[ n ].
    It's the same with an expression too, but you have to take care to parenthesize it:
    Code:
    #include <stdio.h>
    
    int main ( void )
    {
      const char *p = "This is a test";
      
      puts ( &( 2 * 2 + 3 / 2 )[p] );
      puts ( &p[2 * 2 + 3 / 2] );
    
      return 0;
    }
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newb Help: Full Arrays and Functions
    By LycanGalen in forum C Programming
    Replies: 5
    Last Post: 01-31-2008, 08:35 PM
  2. Game Won't Compile
    By jothesmo in forum C++ Programming
    Replies: 2
    Last Post: 04-01-2006, 04:24 PM
  3. Need help understanding info in a header file
    By hicpics in forum C Programming
    Replies: 8
    Last Post: 12-02-2005, 12:36 PM
  4. Replies: 4
    Last Post: 11-23-2003, 07:15 AM
  5. A Simple (?) Problem
    By Unregistered in forum C++ Programming
    Replies: 8
    Last Post: 10-12-2001, 04:28 AM