#1
  1. No Profile Picture
    Dazed&Confused
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2002
    Location
    Tempe, AZ
    Posts
    506
    Rep Power
    128

    C, sprintf - Displaying percent signs


    I'm currently using sprintf's to create query strings for database calls. Using a MySQL format command, I need to keep quite a few percent signs literal for it to do it's job. Upon reading I found that using '%%' in the string should create literal percent signs, however it's not working in my percent-filled string. Here's my code, followed by an example of the actual string after the sprintf call.

    Code:
    sprintf( query_string, "SELECT UNIX_TIMESTAMP(FROM_UNIXTIME(%lu,'%%Y%%m%%d%%H0000'))", otop );
    Output:
    SELECT UNIX_TIMESTAMP(FROM_UNIXTIME(1041404400,'%YSuccess134544160%H0000'))

    Any suggestions?

    Thanks in advance
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,161
    Rep Power
    2222
    I'm afraid this isn't going to help you much. I copied and pasted your code in to a test program and it worked for me.

    Here's a "screen dump" showing the program and its output. I compiled with MinGW's gcc:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        char query_string[100];
        unsigned long otop = 1041404400L;
    
        sprintf( query_string,
          "SELECT UNIX_TIMESTAMP(FROM_UNIXTIME(%lu,'%%Y%%m%%d%%H0000'))", otop );
    
        printf("%s\n",query_string);
    /*
    Output:
    SELECT UNIX_TIMESTAMP(FROM_UNIXTIME(1041404400,'%YSuccess134544160%H0000'))
    */
    
        return 0;
    }
    
    ~
    ~
    ~
    "sprint.c" 21 lines, 394 characters
    
    C:\dcw\PROJECTS\TEST>gcc sprint.c
    
    C:\dcw\PROJECTS\TEST>a
    SELECT UNIX_TIMESTAMP(FROM_UNIXTIME(1041404400,'%Y%m%d%H0000'))
    
    C:\dcw\PROJECTS\TEST>
  4. #3
  5. No Profile Picture
    Dazed&Confused
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2002
    Location
    Tempe, AZ
    Posts
    506
    Rep Power
    128
    Huh... well I ended up taking another route to find the information I needed, but thanks for the post. I'm not sure if I should be afraid of a memory leak somewhere or not. I'd say yes because what has happened is odd, but the fact that it was so consistantly wrong (very same output every time) I'm hesitantly ruling out a memory leak.

    Well... we'll see if my program blows up I guess. :)
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,161
    Rep Power
    2222
    Originally posted by dmittner
    Huh... well I ended up taking another route to find the information I needed, but thanks for the post. I'm not sure if I should be afraid of a memory leak somewhere or not. I'd say yes because what has happened is odd, but the fact that it was so consistantly wrong (very same output every time) I'm hesitantly ruling out a memory leak.

    Well... we'll see if my program blows up I guess. :)
    If your compiler was interpreting some of those double-%'s as format specifiers, then the weird results would be a symptom of having more format specifiers than variables.

    sprintf has an array of variables from which to get the values that it is going to format, so it just keeps on going whether you had put anything there or not. In the case where you give it one variable but there are three format specifiers, then the first variable value will go in as expected and then for the second and third it will be reading garbage and you get really wild results. So if that happens, you need to check that you have provided one variable for each format specifier.

    In this case, it shouldn't have happened, but for some reason it looks like your compiler misinterpreted what you wrote. Could you tell us what your compiler is?
  8. #5
  9. No Profile Picture
    Dazed&Confused
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2002
    Location
    Tempe, AZ
    Posts
    506
    Rep Power
    128
    I'm compiling with gcc.
    Considering the output I was getting, it seems as though it was recognizing %%m and %%d as format specifiers, since the leading percent wasn't kept-- but then it might exclude that for having no recognized completion.
  10. #6
  11. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    Originally posted by dwise1_aol
    In the case where you give it one variable but there are three format specifiers, then the first variable value will go in as expected and then for the second and third it will be reading garbage and you get really wild results.
    -actually what happens is pretty cool. if you do something like this:
    Code:
    int x = 8; int *ptr = &x;
    
    printf("x address is: %p\n", ptr);
    printf("stack dump: %08x : %08x : %08x\n");
    will output:
    x address is: 0xbffffb04
    stack dump: bffffb04 : bffffb08 : 08048246

    you can rip values right off of the stack and get a dump of the stack memory:D
  12. #7
  13. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,161
    Rep Power
    2222
    Originally posted by dmittner
    I'm compiling with gcc.
    Considering the output I was getting, it seems as though it was recognizing %%m and %%d as format specifiers, since the leading percent wasn't kept-- but then it might exclude that for having no recognized completion.
    My previous test was run on Windows 98 using the MinGW port of gcc. I just compiled and ran the exact same program on Red Hat 7.0 using gcc version 2.96 20000731 (Red Hat Linux 7.0). I got the same results; it still works for me.

    Just as a wild idea, copy my program from the previous post and compile and run it. See if you get the same results as I do. I'm not getting my hopes up, because I had copied and pasted your sprintf statement from your post, but it still might be worth a try. At least it couldn't hurt ... much.
    Last edited by dwise1_aol; June 17th, 2003 at 02:22 PM.
  14. #8
  15. /(bb|[^b]{2})/

    Join Date
    Nov 2001
    Location
    Somewhere in the great unknown
    Posts
    5,163
    Rep Power
    792
    I would say to try dwise1_aol's example program also. If it works and yours doesn't, you might want to check to see if enough size was allocated to the variables that you are using.

IMN logo majestic logo threadwatch logo seochat tools logo