A.s. Bhullar
A.s. Bhullar

Reputation: 2788

Ternary operator inside printf

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.

Upvotes: 7

Views: 22678

Answers (9)

Abhinav Kathuria
Abhinav Kathuria

Reputation: 21

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.

Upvotes: 2

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158589

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.

Upvotes: 10

chux
chux

Reputation: 154127

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;
}

Upvotes: 1

rom1nux
rom1nux

Reputation: 120

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.

Upvotes: 2

Ayush
Ayush

Reputation: 2618

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

Therefore, Hello gets printed in both situations

Upvotes: 1

Mickey
Mickey

Reputation: 490

There is a statement of the form: condition?consequent:alternative.

The condition is checked, and if it's true you'll get the consequent. otherwise you'll get the alternative.

For example:

5>3 ? 10 : 5

5>3 is true, so you'll get 10.

Upvotes: 0

Wojtek Surowka
Wojtek Surowka

Reputation: 21003

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.

Upvotes: 4

ThiefMaster
ThiefMaster

Reputation: 318598

The ternary operator is simply an inline if that's used as an expression (while a regular if is used to create a block). Your line is equal to this:

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

Upvotes: 1

Rahul Tripathi
Rahul Tripathi

Reputation: 172568

Does it mean I am wrong in interpreting syntax of printf()?

No you are not interpreting it wrong.

Does placing ternary operator inside printf() is a special case?

In C, you can say that its an expression instead of a statement

Your code is equivalent to:

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

Upvotes: 1

Related Questions