1

I am reading the book "The C Programming Language" by Brian Kernighan and Dennis Ritchie(2nd edition, published by PHI). In the first article 1.1 Getting started of the first chapter A Tutorial Introduction, page number 7, they say that one must use \n in the printf() argument, otherwise the C compile will produce an error message. But when I compiled the program without \n in printf(), it went fine. I did not see any error message. I am using Dev-C portable with "MinGW GCC 4.6.2 32-bit" compiler.

Why I do not get the error message?

Jongware
  • 22,200
  • 8
  • 54
  • 100
user31782
  • 7,087
  • 14
  • 68
  • 143

3 Answers3

9

Here is the passage in question, from page 7 of the second edition of K&R:

You must use \n to include a newline character in the printf argument; if you try something like

 printf("hello, world
 ");

the C compiler will produce an error message.

This means that you can't embed a literal newline in a quoted string.

Either one of the lines below, however, are fine:

printf("hello, world");   /* does not print a newline */
printf("hello, world\n"); /* prints a newline */

All the text above is saying is that you can't have a quoted string that spans multiple lines in the source code.

You can also escape a newline with a backslash. The C preprocessor will remove the backslash and newline, so the following two statements are equivalent:

printf("hello, world\
");
printf("hello, world");

And if you have a lot of text, you can put multiple quoted strings next to each other, or separated by whitespace, and the compiler will join them for you:

printf("hello, world\n"
       "this is a second line of text\n"
       "but you still need to include backslash-n to break each line\n");
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
yellowantphil
  • 1,483
  • 5
  • 21
  • 30
  • You *can* break a literal string across multiple lines. Distinguish between the source and output. See http://stackoverflow.com/questions/797318/how-to-split-a-string-literal-across-multiple-lines-in-c-objective-c – Weather Vane Dec 03 '14 at 18:07
  • Yes, now I am getting the error. I misunderstood it. Thank you for explaining. – user31782 Dec 03 '14 at 18:12
  • @yellowantphil Is there some other programming website for beginners in SE, where all type of programming question are allowed. – user31782 Dec 03 '14 at 18:17
  • 2
    @user31782 I don't think so, but I'm not entirely clear on what questions belong where. I don't know why this question got downvoted though. – yellowantphil Dec 03 '14 at 18:19
  • @yellowantphil: it got downvoted because its not a conceptual question regarding software development, and is instead a question about a specific book about a specific language, which belongs on SO. – whatsisname Dec 03 '14 at 18:21
  • @whatsisname All the downvotes came after the question was migrated. I do not have any problem with voting. All I want is that the question does not get deleted. – user31782 Dec 03 '14 at 18:22
  • 1
    The `\n` is also important as a guarantee that the buffer is flushed, ie. anything prints at all. Either that or manually call `fflush(stdout);`. – SnakeDoc Dec 03 '14 at 22:58
3

You don't get a compile-time error message because there is no error.

In the first article they say that one must use \n in the printf() argument, otherwise the C compiler will produce an error message.

Can you cite (by section and/or page number) where that statement appears? I seriously do not believe that K&R (you're using the second edition, right?) says that. If it did say that, it would be an error in the book.

Update: What the book says, quite correctly, is that a newline in a string literal is represented by the two-character sequence \n, not by an actual newline character. A string literal must be on a single logical source line; something like

printf("hello
world");

is a syntax error. This applies to all string literals, whether they're printf format strings or not.

An actual newline in a string literal is an error. A \n sequence that represents a newline is optional; its lack is not an error, but a printf format string should usually end with a \n.

There is no requirement for a printf call to include the \n character, and I've never seen a compiler complain about a printf that lacks a \n.

There is an issue here, but it's not a compile-time error.

Some examples:

printf("No newline");

This is a perfectly legal call. It prints the specified string on standard output without a newline character.

printf("hello%c", '\n');

There's no \n in the format string, but it prints hello followed by a newline. Again, this is perfectly legal.

The actual issue is that you should (almost) always print a newline at the very end of your output. This complete program:

#include <stdio.h>
int main(void) {
    printf("hello");
    return 0;
}

is legal, but its behavior may be undefined in some implementations. The relevant rule is in the standard, section 7.21.2 paragraph 2 (the quote is from the N1570 draft):

A text stream is an ordered sequence of characters composed into lines, each line consisting of zero or more characters plus a terminating new-line character. Whether the last line requires a terminating new-line character is implementation-defined.

Whether that terminating newline character is required or not, it's (almost always) a very good idea to end your output with a newline. If I run it on my system, I get the string hello immediately followed by my shell prompt on the same line. It's not illegal, but it's inconvenient and ugly.

But that applies only at the very end of the program's output. This program is perfectly valid and has well defined behavior:

#include <stdio.h>
int main(void) {
    printf("hello");
    putchar('\n');
    return 0;
}

Still, the easiest and most reliable way to produce clean output is for each printf call to print exactly one line, which ends with exactly one '\n' character. This isn't a universal rule; sometimes it's convenient to print a line a piece at a time, or to print two or more lines in a single printf.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • I have *never* had trouble with this sort of thing: `printf("Some of Line 1"); printf(". More of Line 1\nLine 2\n");` – Weather Vane Dec 03 '14 at 17:25
  • @WeatherVane - `stdout` gets flushed by your second call to `printf` which has a newline character. In the example in the answer, there is only one `printf` call and the newline character is never sent to `stdout`. You _may_ not see your output if you use the example in the answer. –  Dec 03 '14 at 17:27
  • @WeatherVane: I wouldn't expect you to have any trouble with that. Did you think my answer implied that you would? – Keith Thompson Dec 03 '14 at 17:28
  • I think user31782 was asking about the text at the bottom of page 7, just after the chapter introduces the `\n` sequence. It says that you have to use `\n` to get a newline, rather than just hitting enter inside a quoted string. – yellowantphil Dec 03 '14 at 17:32
  • @Keith Thompson I was agreeing with you. Lack of newline isn't a problem especially if a tidy program makes sure there is one before exit. – Weather Vane Dec 03 '14 at 17:33
2

Very often, if you don't end your printf format string with a \n, some of the output stays in the stdout buffer, and you need to call fflush to get all the output shown.

This means that if you don't get all the expected output you should add fflush at appropriate places (e.g. before calls to fork).

But you won't get a compiler message in such case, because it is not an error (it may be a mistake many beginners are doing). If you really wanted, you could customize your compiler (e.g. with MELT if using a recent GCC compiler) to get the warning. I believe it is not worth the effort (because there are legitimate calls to printf without any \n....)

An example of legitimate printf calls without newlines would be if you coded a (recursive) function to output an expression from its AST; you certainly should not emit a newline after each token.

See documentation of printf(3), fflush(3), stdio(3), setvbuf(3) etc...

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • I get all the output. What kind of output stays in? I am new to programming, I don't know how to customize a compiler. Could you show me a screenshot of error the compiler should show. – user31782 Dec 03 '14 at 17:48
  • @user31782 You won't notice buffering, unless your program prints a lot of output. Then, you sometimes won't see what you printed in the terminal right away. – yellowantphil Dec 03 '14 at 17:59
  • @user31782: no, and I believe that expecting the compiler to give diagnostics on `printf` without `\n` is not realistic – Basile Starynkevitch Dec 03 '14 at 18:02
  • @user31782 if your program just prints a line then terminates, it probably will flush the buffer (ie. print the line), however if you have a lot printing and/or your program has a long run-time, omitting the `\n` will often cause your output to remain in the buffer. You can either print the `\n` character, or manually call `fflush(stdout);` to flush the buffer and cause your text to print. – SnakeDoc Dec 03 '14 at 23:02
  • @SnakeDoc How much should I print so as to observe this effect? One thousand characters...? – user31782 Dec 04 '14 at 08:29
  • @user31782 there's no right answer... it will depend on the system you are using, etc. So the same program may even vary in behavior slightly on different systems. It's generally good practice to do it anyways, even if it's just a single `fflush(stdout);` or `printf("\n");` at the end of your program during a cleanup routine (ensuring your shell prompt returns to a new line). – SnakeDoc Dec 04 '14 at 15:45
  • @user31782 For an example program which actually counts on the buffering to occur, visit this link: https://github.com/SnakeDoc/CSc60/blob/master/7/parent.c#L176 -- It `printf`'s each time a child process exits but nothing displays on-screen until the final `printf("\n");` is called. – SnakeDoc Dec 04 '14 at 15:45
  • @SnakeDoc I do not know many things that you talk about, e.g. fflush. I am noob in programming. I tried to print 100,000 characters without `\n`, it went fine. – user31782 Dec 04 '14 at 15:48
  • @user31782 When you `printf`, you are sending your string into the standard out buffer (stdout), which is usually your screen/terminal. That buffer can hold many things, and depending on your system/terminal, it may or may not automatically flush itself (that's when it actually takes the contents of the buffer and pushes them to the screen, ie. prints to the screen). With `printf`, having the `\n` character will force it to flush the buffer immediately. However if you do not, there is no guarantee that the buffer will flush. If the buffer gets full, it will likely flush itself. – SnakeDoc Dec 04 '14 at 15:58
  • 1
    @user31782 in your example code, put a `sleep(10);` after your `printf` loop, you will notice it likely prints up to a certain point, then stops (even though it's outside the `printf` loop, after the sleep finishes), the remainder will likely print. That is the stdout buffer being flushed. Something like: `main() { int i; for ( i = 0; i < 100000; i++ ) { printf( "%d ", i ); } sleep( 10 ); }` --- on my system it stops after printing 99984... – SnakeDoc Dec 04 '14 at 16:05
  • @SnakeDoc `sleep()` doesn't work on my system. I have used `Sleep()` with . I am getting `99999`. – user31782 Dec 06 '14 at 15:29
  • @user31782 the point is that when your system sleeps, it's probably paused before it's printed the entire buffer (that is unless the windows buffer is smaller and therefore flushes more often). After the sleep finishes, your program is terminating and your system may or may not flush the buffer. In any event, if you want your C code to be portable, you should not rely on the buffer being flushed for you... that's just bad programming. – SnakeDoc Dec 06 '14 at 21:22