Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

The magic and flexibility of printf (part 2)

c

  • Please log in to reply
3 replies to this topic

#1 fkl

fkl

    CC Devotee

  • Senior Member
  • PipPipPipPipPipPip
  • 417 posts

Posted 31 October 2012 - 11:22 AM

I am continuing with printf as a follow up to Part 1.
 
Also, check out our tutorials on scanf and sscanf!

This tutorial would explore some thorough usage of printf and will talk about some scenarios that are not very frequently seen or encountered.

However, apart from merely trying to show “WOW! I didn’t know this can be done with printf”, I would try to cover all possible usages that are applicable in writing practical software applications.

One fundamental but common ignored aspect of printf is the return value. It returns the number of characters written.

So

printf("%d\n", printf("")); // %d is used to print a signed integer

would print 0 where as

printf("%d\n", printf("Hi\n"));

would print 'Hi' (quotes only for clarity) on one line followed by a 3 on the next line. Note that ‘\n’ is also counted as a character written but the string terminator ‘\0’ in “Hi” is ignored since it is not printed.

Now applying this approach to variables, there is an important point to remember. Say you have a string containing a %d (the second one in below e.g.) used by printf. Now this %d represents an integer a whose value is 124. Because this is converted to a string and printed on the screen, it would return the count of characters i.e. number of digits in a (which are 3) plus 1 for the newline character (‘\n’). Hence the below code should print 124 on first line followed by 4 on the next line. If we had a six digit number printed, function would return 6 plus 1 for the newline.

int a = 124;
printf("%d\n", printf("%d\n", a));

This is a useful aspect of the function which can be of help for error checking. At the very least it can provide insight to code about what was printed.

Whenever you need to print an address of a variable (a pointer precisely), use %p

int var = 12;
printf("%p\n", &var); // printed 0044FA98 on my windows 7 64 bit machine

It is important to understand that pointer is an address and can only be used correctly when it actually points to a valid memory location.

Doing a printf on int *p; can have undefined result. Some compilers would complain an uninitialized pointer, where as others might crash.

Similar to how we can specify a flag such as ‘-’ or ‘+’ for left justification in between “%” and “d”, we can also specify some more characters such as ‘#’ or ‘0’ i.e.

int v = 10;
printf("%#x\n",v); // would print 0xa

Note the prepended 0 in the beginning. Without the # it would have simply printed ‘a’. ‘#’ prepends 0x to hex or 0 only to octal value. Similarly a 0 can be used in place of #. It’s implication is when width of a field is specified already using %[width] e.g. %7 (7 characters wide field), then a prefixing ‘0’ would fill the empty spaces with 0’s.

The complete format of printf string is

%[flags][width][.precision][length]specifier

http://www.cplusplus.../cstdio/printf/

Where specifier is something like d, f or u. Flags is one of +,-,# etc. width is an integer width of the field, precision is the number of digits to be printed after the decimal and length is the specifier which qualifies the length of a type precisely.

An example of usage of length field is

__int64 var = 232132112112; // on windows
long long var = 232132112112; // on linux

To correctly print the above we would use a %d with ll prefix for long long. This ‘ll’ specifies the length of integer.

printf("%lld\n",var);

Now moving towards a few insane examples of printf

What do you think will be the output of the following?

printf("%3%2\n");

The weird part of course is that format string contains two % arguments but no specifier and no follow up arguments. Yet it compiles and does produce some predictable results.

The first argument after % is taken as width of field i.e. 3 and hence is not printed. However, it expects a specifier latter instead of which it finds another %. Standard says % followed by % prints it to stdout. Hence you should see % printed first. Now because effect of % is lost, so 2 is treated and printed as a normal number.

Therefore, above code fragment prints %2 on the screen.

Another interesting example

printf-2.png

A double by default with %f should print six places after the decimal. However, specifying precision with a ‘.’ followed by integer value in between % and f is something already known.

The additional part here is that you can put in a * in place of that integer value and put a variable after the formatted string. * indicates that the value should be picked up from parameters. Hence the constant 2 in the above example indicates the precision of 2 places after the decimal. Once can easily replace this 2 with a variable. Note that this variable should be placed before the actual double variable i.e. fvar in this case.

 

Don't forget to read up on our tutorial on sscanf!


Edited by Roger, 19 February 2013 - 02:39 PM.
add links

  • 0
Today is the first day of the rest of my life

#2 annalake123

annalake123

    CC Lurker

  • New Member
  • Pip
  • 3 posts

Posted 17 November 2015 - 02:11 AM

Answer as a new post .

1) What are the rules when writing pseudocode?

2) What is the difference between pseudocode and a programming language VB?

3) [If you’ve done GCSE Computing] For the following pseudocode write a VB.NET equivalent:

for x from 1 to 7 inclusive
add x to total
loop
print total

4) Write pseudocode for the following problem:

Find the average of 4 numbers and display it
 

Hand Car Wash Sydney


  • 0

#3 annalake123

annalake123

    CC Lurker

  • New Member
  • Pip
  • 3 posts

Posted 27 January 2016 - 01:53 AM

#define PRINTCHAR(c) putchar(c)
#define MAXLEN 256

// Write a printf function which simulates printf() in C.
int formatAndPrintString(char *pcFmt, va_list lList)
{
    //Holds the number of characters printed, 0 on error
    int nChars = 0;

while(*pcFmt != '\0')
{
    if(*pcFmt == '%')
    {
        pcFmt++;

        int iTemp = 0;
        char acTemp[MAXLEN] = ""; 
        char *pcTemp = NULL, cTemp = 0;

        switch (*pcFmt)
        {
        case 'd':
            iTemp = va_arg(lList, int);
            itoa(iTemp, acTemp, 10); 

            for(int i = 0; i < strlen(acTemp); i++)
            {
                PRINTCHAR(acTemp[i]); nChars++;
            }
            break;
        case 's':
            pcTemp = va_arg(lList, char*);

            while(*pcTemp != '\0')
            {
                PRINTCHAR(*pcTemp); nChars++;
                pcTemp++;
            }
            break;
        case 'c':
            cTemp = va_arg(lList, int);  
            PRINTCHAR(cTemp);
            nChars++;
            break;
       default:
          break;
       }
       pcFmt++;
    }
    else 
    // print the char to console
    {
       PRINTCHAR(*pcFmt);
       pcFmt++; nChars++;
    }
}
return nChars;
}

// Print function identical to printf() in stdio.h
int printfunc(char *pcFormat, ...)
{
    if(!pcFormat)
    {
        return 0;
    }

    va_list lList;
    va_start(lList, pcFormat);

    return(formatAndPrintString(pcFormat, lList));
}

200-120 Pass4sure

 


  • 0

#4 Biwaan

Biwaan

    CC Lurker

  • Just Joined
  • Pip
  • 1 posts

Posted 20 July 2016 - 05:44 AM

Now this %d represents an integer a whose value is 124. Because this is converted to a string and printed on the screen, it would return the count of characters i.e. number of digits in a (which are 3) plus 1 for the newline character (‘\n’). Hence the below code should print 124 on first line followed by 4 on the next line.


  • 0





Also tagged with one or more of these keywords: c