C, why does printf add a "D" after a single digit long? - c

I'm working through the K&R C book and one of the example programs is this:
#include <stdio.h>
int main() {
long nc;
nc = 0;
while (getchar() != EOF) {
++nc;
}
printf("%ld", nc);
return 0;
}
When I run this program, it mostly behaves as I expect. So for an input like This is a sentence, it prints 19.
However, if I input anything under 10 characters (including EOF), there is a capital D appended to the output number.
E.g. for input hello, the output is 6D.
Why is there a D appended to an integer value and what does it mean?
Note: This occurs with cc, gcc and clang.

It turns out that D is part of the ^D that gets printed to the console when I input an EOF (control + D on Unix). Because there is no \n at the start of the printf statement, a single-digit number will overwrite the ^, while a double-digit number will overwrite the entire ^D, which is what gave the impression of some weird behaviour.

What version of gcc are you using? I ran the exact same code using gcc and it runs fine. Maybe it's an artifact left over by your terminal where it's trying to print the Ctrl-D for end of file

Related

C beginner for-loop output issue

I am new to C (self-learning).
When I execute this for-loop function when I type 'hello' the output will be 012345. However it skips to last print function outside of the for-loop?
int main() {
int c;
for (c = 0; getchar() != EOF; ++c) {
printf("%d\n", c);
}
printf("%d\n", c);
return 0;
}
The output:
hello
0
1
2
3
4
5
"When I execute this for-loop function and I type 'hello' the output will be 012345".
What do you expect else? c just get incremented by each iteration, starting at 0.
"However it skips to the last print function outside of the for-loop?"
No, it doesn´t. In fact, It isn´t even out of the for loop. The newline made by the press to Enter doesn´t let you break out of the loop; only a signalized EOF is doing that.
So, the program isn´t even terminated. It stucks in the loop.
You need to signalize EOF with CTRL + D on Linux or CTRL + Z on Windows to break out of the loop.
No it is not skipping anything.
Note: you are printing c which is integer (not character, if that is what you want). So, input "hello" has 5 characters: so, output is:
0
1
2
3
4
Then, as there is newline character '\n' as you pressed enter (there is your output 5). However, you loop never exits, unless you force program to do so (I mean, interrupting with Ctrl +C). If you, test again your code, and input data even after "hello", you will see that, you are still in the loop.
Change your program to this:
#include <stdio.h>
int main() {
int c;
int ch;
for (c = 0; (ch = getchar()) != EOF; ++c) {
printf("%d %d\n", c, ch);
}
printf("%d %d\n", c, ch);
return 0;
}
Now you should understand yourself what happens.
The while loop doesn't end when you type hello and presses Enter, because getchar() still won't be equal to EOF. So the loop will continue with getchar() waiting to read new characters.
You need to press Ctrl+Z on Windows' cmd.exe, or Ctrl+D on Linux's terminal, to proceed with the execution of the program without writing any character to the input, then getchar will fail to read a character and return EOF, finally exiting the loop. Once it is out of the loop the final printf call will be made before ending the program.
Alternatively you could change the condition to make the loop end when getchar reads a new line character \n, instead of when it fails to read a character, so that the loop will end after you press Enter:
int main() {
int c;
for (c = 0; getchar() != '\n'; ++c) {
printf("%d\n", c);
}
printf("%d\n", c);
return 0;
}
I see what you're tryng to do, but first of all i'd declare "c" as a char , this way you're doing an implicit cast to char, which is allowed in C language, but should be avoided.
My best guess would be that you'r compiler (i suppose mingw on windows) is not telling you what's going on exactly, try this:
When you build (compile) something outside linux for C language do as follows :
" gcc -o nameoftheexecutable file.c -Wall " and to execute it " ./nameoftheexecutable
That -Wall will print out all warnings to the console, including EOF warnings.
By doing this, and understanding what IDE or Environment are you programming in, we can help you out.

scanf character input/output

scanf not working as expected with a normal input character
So I was just trying out the scanf() and a normal input/output of this function. I know that I had to leave a space before the input character and the operand% so my code is as below. Somehow I don't understand why whatever the input I inserted the output remains 0.
#include<stdio.h>
int main()
{
char c ;
scanf(" %c",&c);
printf("%c",c);
return 0;
}
I was expecting the output will be whatever the character I insert. For example, insert an "A" via keyboard and the output will be exactly an "A".
I'm using a vim environment to edit my code, but I found that if I run this code on codeblocks it works. What's the difference?
It appears you are not providing any non-whitespace (which are eaten away by th space in the format string, including newlines) characters (or perhaps nothing at all) from standard input. If this happens, scanf will fail to parse a char and leaves c uninitialized.
Using uninitialized variable is is Undefined Beheavior, so in theory anything could happen. In practice, from your description, it sounds like memory reserved for c happens to have byte value 0, which is unprintable character, so printf prints something else (maybe /0, maybe nothing). And then the environment (vim) might show you the program exit code, also 0 here (assuming the Undefined Behavior doesn' cause your program to crash).
To fix this, check return value of scanf:
#include<stdio.h>
int main()
{
char c ;
int r = scanf(" %c",&c);
if (r==1) {
// Always print something and add newline
// to be sure we see some output always.
printf("c='%c'\n",c);
} else {
printf("scanf error: %d\n", r);
// If r==-1, errno variable tells what error was
}
return 0;
}
Practical hint: To provide standard input when there is no terminal (so you can't type the input), you can pipe something:
echo A | ./thisprogram
I've tried to run your program (exactly as it appears in your question)
pru.c
#include<stdio.h>
int main()
{
char c ;
scanf(" %c",&c);
printf("%c",c);
return 0;
}
and with the input you posted in your question (just A plus Enter) and got the following result:
$ cc pru.c
$ ./a.out
A
A$ _
which is exactly the expected output. So the problem must be in another place, or you have a completely different scenario and need to provide more information.
I tested this on a PC (Intel Core Duo) with FreeBSD 12.0/CLANG compiler. (here $ is the unix prompt and _ is the cursor after the run) And of course, the program has been edited with vi(1) (this has no impact on the result).
Edit
Try to change
printf("%c",c);
by this
printf("0x%02x, [%c]\n",c,c);
so, you'll get an hex dump of the character just input, and also its representation as printed. The \n at the end is to ensure your shell prompt is not eating (overwriting) the last line output of your program (mostly if you have changed the prompt variable PS1) hidding the printed char.
That should produce (on your posted input) the following output:
$ cc pru.c <--- compilation of new pru.c
$ ./a.out <--- default name for your program executable.
A <--- this is your input (followed by <return>)
0x41, [A] <--- this should be your program output.
$ _ <--- prompt (and cursor) after your program execution

Why is this character counting program in C doubling the value of the characters?

This example is from "The C Programming Language" by Dennis Ritchie and Brian Kernighan. It is supposed to take in characters given by user input, and then when an EOF is stated (using my Mac, it is ctrl-D), it ends the program and shows the amount of characters inputted. Instead it doubles the actual value of the amount of characters. Am I missing something? Thank you.
#include <stdio.h>
main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%1d\n", nc);
}
It is not doubling the value, for example if you type :
a
b
c
Ctrl+D
you will see 6 cause there is a line break after each character like:
a\n
b\n
c\n
Ctrl+D
\n is considered as a character (if am not wrong, in mac the line break character is \r).
if you type :
abc
Ctrl+D
you will have 4 characters because of the line break at the end of the abc sequence.
NOTE : as other members noticed you are using the wrong formatting character for long type, it must be %ld but you are using %1d (1 instead of l) i think it is a mistake when you copied the code.
hope that answer you question.

getchar() function bypasses one loop

I have this program and I want it to increment by one and print the value of my counter each time I give a character
#include <stdio.h>
int main(void){
//Declarations
long nc;
//Instantiations
nc = 0;
while (getchar() != EOF){
++nc;
printf("%ld\n", nc);
}
return 0;
}
When the loop initiates if I press ENTER I get 1,2,3,4,5... which is ok.But if I type a character or something else it prints the next two numbers 12,34,56,78. Why is that happening??
I am running the program on gcc 4.6.3 Ubuntu 12.04 release.
Terminal input is normally line buffered. Your program only gets input to process when you press ENTER. If you type several characters, you will get one line of output for each character you input (plus the newline itself) as getchar() returns each character in sequence.

Counting chars in C on Mac OS X

I am running an example from The C Programming Language by Kernighan and Ritchie.
#include <stdio.h>
main() {
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
I'm on Mac OS X, so I compile it, run it, type in "12345", press enter for newline (I believe newline is the sixth character?) and then press ctrl-D to send an EOF.
It prints out "6D".
Why is the "D" there?
How do I write a program to just count the 5 chars in "12345" and not the newline?
Should I just subtract one at the end?
How do I get it to stop printing the "D"?
What happens is that the terminal actually echoes your control-D (and prints it out as ^D) when you type it, but then your program overwrites that line with a number and a line-feed. So your one-digit number overwrites the ^, but the D stays there.
If you enter more than 10 characters, or if change the code by adding a space at the end of your format string ("%ld \n"), then your program would overwrite the ^D (though it would still have been echoed by your terminal)
The program is working correctly: it's printing 6.
You see 6D because the terminal window printed ^D then went back to the beginning of the line, and your program prints 6 over the ^ leaving the following D. Try redirecting the output to a file, or giving it enough input that the answer has more than one digit, and you won't see the D.
The answer is 6 instead of 5 because of the newline, yes. If you don't want to count the newline at the end, subtract 1. If you don't want to count any newlines, subtract 1 whenever you see a newline.

Resources