• C

%06.6ld format specifier- what does it do?

Hello,
In the following program, I was trying to
experiment with the %06.6ld format specifier.
I was thinking that even if the number "passed"
to it was > 6 digits, it would cut off at 6, unlike
the %06ld specifier.


void main()
{
        char buff[26];

        long num;

        printf("Enter a long:\n");
        gets(buff); num=atol(buff);
        printf("num(06ld)=|%06ld|\n", num);
        printf("num(06.6ld)=|%06.6ld|\n", num);

      
}

However,
that was not the case. For the number 1234567,

Enter a long:
num(06ld)=|1234567|
num(06.6ld)=|1234567|

So...does this mean that %06.6ld has no effect?
or, does it do something else?

Thanks,
St eve
LVL 4
Stephen KairysTechnical Writer - ConsultantAsked:
Who is Participating?
 
Kent OlsenData Warehouse Architect / DBACommented:
Hi stevefromc,

This quirk has only come up in the C forum a couple of times.  :)  One of the little known behaviors of the 'd' format specifier is that it guarantees that all of the significant digits of the integer will be displayed.  Regardless of the modifiers, if the number contains 7 digits, 7 will be displayed even if the format spec calls for less.  If you want less displayed, you'll have to perform modulo arithmetic to ensure that the value is not longer than the number of digits that you want.

         printf("num(06.6ld)=|%06.6ld|\n", mod(num, 1000000));

Strings are a different matter.  The C library will truncate the string to the desired length, but not so with integers.


Good Luck!
Kent
0
 
cupCommented:
If your number is bigger than the format specified, the format is ignored and the machine normally does the best it can to give you the value that it has.

 If I told you to print 6 digits and gave you an 8 digit number, would you print the first 6, middle 6 or last 6?

If you only want 6 digits, no matter what the size, sprintf it to a character array first then truncate the array accordingly.
0
 
Stephen KairysTechnical Writer - ConsultantAuthor Commented:
Kent,,
OK, so my compiler is not "buggy" in that it does not truncate to 6. Good to know. That being said, here's the crux of the matter:

I was actually MORE concerned about if
a 6-digit number would be handled correctly i.e.
if I pass it "123456" (intending that it display as "123456"),
will C behave "properly", or will it, under some
cases, cause MORE than 6 digits to be ouputted?
Reason I ask is that I'm tracking down a possible
memory oerwrite and wondered if

char buff[7];
sprintf(buff, "%06.6ld", some_number)

could ever overflow BUFF for a number that
I know won't ever exceed 999999....I was thinking
that if this format spec were somehow "illegal" that
I could be asking for trouble... :)

Thanks,
Steve



0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
Kent OlsenData Warehouse Architect / DBACommented:
Hi stevefromc,

Well, if some_number can ever exceed 999999 then buff will certainly overflow.  But if you're sure that it can't exceed 6 digits then you're safe.  On the other hand, memory is cheap.  Defining the buffer as char buff[20] doesn't hurt a thing.

One of the little used features of sprintf() is that it returns the number of characters written to the output string.  In this case it would be trivial to check the return value and spit out an error message if it exceeds the buffer size.  But that does take CPU cycles and an entire program's worth may not be worth the trouble.  It's faster and more efficient to arbitrarily define a larger buffer.

That said, the return value of sprintf() is extraordinarily convenient for some functions.  Imaging trying to pack comma delimited values into a buffer when you don't know how many values there are:

  int    Array[100];
  char Buffer[1000];
  int    Length;
  int    idx;

  Length = sprintf (Buffer, "%d", Array[0]);
  for (idx = 1; Array[idx]; ++idx)
    Length += sprintf (Buffer + Length, ",%d", Array[idx]);

Array[Length] is always the next available character in the buffer so it's easy to append the new value without having to hunt for the end-of-string every pass.


Sorry for getting off track,
Kent
0
 
PaulCaswellCommented:
Hi stevefromc,

If you can GUARANTEE that the number will never go beyond 6 digits then you are fine. I personally would surround it with 'if ( number < 1000000 )' and a comment, perhaps in capitals with stars around it, explaining the problem. Remember the programmers who are yet to work on your code. :-)

'scanf' is a different matter, scanf ( ..."%6.6ld"... ) will read only up to 6 characters and no more!

Paul
0
 
Stephen KairysTechnical Writer - ConsultantAuthor Commented:
OK, I think i'm good here. Thank you all for your help.

And, Kent, no apology neded.. very interesting (and useful) info about sprintf()!! Thank you.

Thanks as well to cup and Paul. Points split.
Steve
0
 
Stephen KairysTechnical Writer - ConsultantAuthor Commented:
..and increasing the total pts.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.