1

I observed some behavior I can't explain myself when using printf to print a character via format-string. It seems that when the character is newline ('\n'), the printf ignores everything up to (including) '%c' and just prints the remaining part.

Here is a minimal example (user input to disable optimization):

#include <stdio.h>
int main(){
  int c;    
  scanf("%d", &c); //read char by ascii id
  printf("FOO%cBAR (id %i)\n", c,c);
  return 0;
}

Entering 45 (the code for '-') results in output "FOO-BAR", but entering 13 ('\n') just prints "BAR". This happens both in gcc 6.3.1 and clang 3.9.1, on -Og and -O3 optimisation levels, on an linux.

This should not be related to output buffering if I'm not mistaken.

Is this behavior intended?

  • 6
    That is because character 13 is "carriage return". So it then overwrites the first part. Newline is character 10. – Weather Vane Mar 22 '17 at 13:23
  • 2
    13 is `\r` not `\n` – Jean-François Fabre Mar 22 '17 at 13:24
  • Oh, I confused '\r' (13) and '\n' (10). So the actual question is why my program stumbled across an '\r'; I might have not used text mode to open my file. I would accept Weather Vane if his comment would be an answer. – Fabian Kunze Mar 22 '17 at 13:33
  • @FabianKunze on some systems when you press Enter you get a `\r\n` rather than just a `\n` – Chris Turner Mar 22 '17 at 13:37
  • "So the actual question is why my program stumbled across an '\r'" --> Consider that the file opened in text mode to read a file may translate `"\r\n"` into `"\n"` or it may not. That translation decision is part of the compiler used. It is not part of the _file read_. So a complier that does not translate `"\r\n"` into `"\n"`, when reading `"\r\n"` will leave that as `"\r\n"`. IMO, use `fgets()` to read a line and then `buffer[strcspn("\r\n")] = '\0';` to lop off _either_ a lone `"\n"` or `"\r\n"`. – chux - Reinstate Monica Mar 22 '17 at 15:03

2 Answers2

2

That is because character 13 is "carriage return".

After that the first part of the message is over-written.

Newline is character 10.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
1

From this answer :

\r is carriage return and moves the cursor back like if i will do-

printf("stackoverflow\rnine")
ninekoverflow

means it has shifted the cursor to the beginning of "stackoverflow" and overwrites the starting four characters since "nine" is four character long.

In this case,

BAR (id %i)\n

will overwrite "FOO".

Community
  • 1
  • 1
Quentin Laillé
  • 125
  • 1
  • 12