Ternary operator inside printf

16,987

Solution 1

The conditional operator:

i>j?"%50s":"%s"

is an expression and it has to be evaluated before the function call itself can be evaluated. We can see this by going to the draft C99 standard section 6.5.2.2 Function calls which says:

An argument may be an expression of any object type. In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument.81)

So what is the result of the evaluation of the conditional operator? If we go to section 6.5.15 Conditional operator it says (emphasis mine):

The first operand is evaluated; there is a sequence point after its evaluation. The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated), converted to the type described below.95

so in either case the result is a string literal which will decay to pointer to char which satisfies the requirement for the first argument to printf.

Solution 2

This code is normal and is not any special case. The requirement for printf is that the first argument should be of the type const char*, but it does not necessarily mean that it needs to be a string literal like "%s". All it means that you need to pass as the first argument an expression of the type const char*. And i>j?"%50s":"%s" fulfils this requirement.

Solution 3

I think you well understood the printf syntax but i think you are missing something about C syntax.

It exist a form of "compact IF like" statement formatted like that : ( condition ? true : false )

For example you can do :

int a=5;
int b=(a==5 ? 128 : 256);
int c=(a!=5 ? 8 : 9);

In this case, b=128 and c=9.

An other example :

int flag=1;
printf("The value is: %s", (flag!=0 ? "true" : "false) );

In this case you can see : The value is true

On your example :

printf(i>j?"%50s":"%s",str);

if i is upper than j you use "%50s" format and, if i is lower you use "%s" format

It can be view like :

if (i>j)
    printf("%50s",str);
else
    printf("%s",str);

You can see the advantage of compact test.

Solution 4

It is a ternary operator and in this the condition i>j is false so %s will be passed as parameter to printf which will print the value of character array which is hello.

Solution 5

Q: Does it mean I am wrong in interpreting syntax of printf()?
A: No, just need to expand what is allowable.

Q: Does placing ternary operator inside printf() is a special case?
A: No ?: is not special, but sometimes confusing at first glance.

The format supplied to printf() does not need to be a literal. It may be any string variable.

int main() {
  char str[]="Hello";
  char *format;
  int i,j;

  i = 5; j = 10; 
  format = i > j ? "%50s" : "%s";
  printf(format, str);

  i = 10; j = 5; 
  format = i > j ? "%50s" : "%s";
  printf(format, str);
  return 0;
}
Share:
16,987
A.s. Bhullar
Author by

A.s. Bhullar

Updated on June 06, 2022

Comments

  • A.s. Bhullar
    A.s. Bhullar almost 2 years

    After reading this I started thinking that I have learned a loot about printf(). Suddenly I found following code snippet from this book:

    int main()
    {
        char str[]="Hello";
        int i=5,j=10;
        printf(i>j?"%50s":"%s",str); //unable to understand this 
        return 0;
    }
    

    Surprisingly above code is running without errors and it prints Hello. As per my knowledge following is syntax of printf():

    int printf(const char *format,argument_list);
    

    So according to this syntax, printf() should start with format string. But as you can see in above code printf() is starting with i>j. Does it mean I am wrong in interpreting syntax of printf()? Does placing ternary operator inside printf() is a special case?

    EDIT

    I know about ternary operator I am asking about first argument of printf() which should be const char* which I seem not in my example.

  • A.s. Bhullar
    A.s. Bhullar almost 10 years
    Can you plz give any example of const char* which is not fully wrapped inside double quotes?
  • Wojtek Surowka
    Wojtek Surowka almost 10 years
    i>j?"%50s":"%s" is of type const char * (technically it is const char [] but it does not matter here) so I guess this is your example. Another example would be func(), where func is a function returning const char*.
  • A.s. Bhullar
    A.s. Bhullar almost 10 years
    Nice explantion!! But I have still doubt in expression i>j?"%50s":"%s" that is I don't think it is const char* ,I think it should enclosed in double quotes marks. Isn't is?
  • A.s. Bhullar
    A.s. Bhullar almost 10 years
    Ok now I understand it that is after evaluating expression only "%s" is passed as a argument to printf()