Printing a char in ANSI C - c

I've used getchar and putchar to succeessfully print my entered char to the screen before, however I've changed the code slightly and now it prints my entered char twice in a row. Code:
#include <stdio.h>
int main()
{
int charInput;
printf("Enter a char >> ");
charInput = getchar();
printf("%c", putchar(charInput));
return 0;
}
I know I could just use putchar without the printf but I wanted to experiment with them. The output I get is:
Enter a char >> a
aa
2 chars are printed to the screen?

The function putchar(charInput) itself print char 'a' and return decimal equivalent of char (e.g ascii) that is printed as char using printf() so total printed two a.
Read Manual page:
int putchar(int c);
The functions, fputc(), putc(), putchar(), putc_unlocked(), and
putchar_unlocked() return the character written. If an error
occurs, the value EOF is returned. The putw() function returns 0 on
success; EOF is returned if a write error occurs, or if an attempt is
made to write a read-only stream.
So you can assume:
printf("%c", putchar(charInput));
// ^ ^ first `a`
// | second `a`
is equivalent to:
temp = putchar(charInput); // first `a`
printf("%c", temp); // second `a`

putchar(charInput) will print your character once, and will then return its argument,
charInput. This then gets passed to printf, which prints the same character again.

This is because one comes fromprintf and another from putchar.
Do only this
putchar(charInput);

Related

How does EOF act in getchar() and scanf() on Windows system?

I have two pieces of codes to test how the two console I/O functions, getchar() & scanf(), handle the EOF. But I still do not have a clear comprehension about the actual operations behind the outputs and their behaviors. Can someone explains that for me? Thanks a lot! (I am using Windows OS)
// 1st piece of Code
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char ch;
while ((ch=getchar()) != EOF)
{
putchar(toupper(ch));
}
return 0;
}
If I type
abc
or
abc(ctrl+z)
The program will have the same outputs:
ABC
// 2nd piece of Code
#include<stdio.h>
int main(void)
{
int x;
while(scanf("%d",&x) != EOF)
{
/*Ctrl + z + Enter*/
printf("x=%d\n",x);
}
return 0;
}
If I type
123
The program will output:
x=123
Otherwise, if I type
123(ctrl+z)
The program will have an infinite output:
x=123
x=123
x=123
x=123
...
getchar() returns the value of the character converted to unsigned char or EOF in case of error.
The error can be "end of file" or something else; usually (for getchar()) the programmer does not care about the error, just that an error happened.
scanf() returns the number of values matched and assigned (basically the number of % in the format string) or EOF in case of error. Note that the number can be less than the number of % in case, for example, of badly formatted input
Just like for getchar() the error can be "end of file" or something else. Particularly, reading less than the number of % is not an error.
So you may prefer to test for the correct number of assignments rather than testing for error in scanf()
#include <stdio.h>
int main(void) {
int x;
while (scanf("%d", &x) != 1) {
/*Ctrl + z + Enter*/
printf("x=%d\n", x);
}
return 0;
}
The problem is that on Windows the EOF is put into the input buffer like a normal character (with the encoded value 26).
When reading character by character (with e.g. getchar) this is handled by the Windows run-time library. But it doesn't work like that with scanf because when scanf parses the input it's like another character. And as a non-digit it's an invalid character for te "%d" format, leading to your scanf Call to return 0 instead of EOF (since it's not parsed by the format).
One way to solve it is to press the Ctrl-Z sequence on its own new line.
Another (and more reliable) way to solve it is to check that scanf returns the number of formats you have in the string. In your case you should compare against 1 (as you have one format specifier).

How to handle less input than expected with scanf - C

I need to receive from the user input that can come in 2 forms, char int float or char int, but I don't know which of them will be given. I tried this:
int main(){
char letter;
int num;
float value;
while(getchar()!=EOF){
scanf(" %c %d %f", &letter, &num, &value);
printf("%c\n", letter);
printf("%d\n", num);
printf("%f\n", value);
}
return 0;
}
The problem with this is when I give an input like this:
? 12345
g 12345 45.6
? 12345
Output given: Expected Output:
1 ?
2345 12345
0.000000 0.000000
1 g
2345 12345
45.599998 45.599998
? ?
12345 12345
45.599998 45.599998
Why is part of the number going in the place of the char and the char is ignored? Is there a way to fix this?
There are several problems here:
The missing char. When you do while(getchar()!=EOF) for the first time, you are consuming the first character in the stream, which happens to be '?'. The subsequent scanf() cannot retrieve that anymore, so it grabs the next non-whitespace character, which happens to be the '1' of the following number.
After that '1' is read, the rest of the number is parsed, providing the result 2345.
The following conversion tries to parse a float, but the next non-whitespace character is a g, so no float can be read, and the conversion fails.
You fail to check, how many conversions are successful. scanf() dutifully returns the number of successful conversions, but you ignore that.
If you had checked the return value, you would have found that the first scanf() call returns 2 because the character and the integer conversions finished successfully, but the float conversion failed.
Likewise, the second scanf() call should have returned 3, signaling that all three conversions succeeded. The last call to scanf() should return 2 again.
The gobbling up of a character in while(getchar()!=EOF) bites you again on the second line, this time it is the 'g' that's removed from the stream before the scanf() gets a chance to read it.
After the second call to scanf() successfully terminates, the '\n' character is left in the stream. Thus, the following while(getchar()!=EOF) gobbles that up, and the third scanf() call can finally correctly fetch the first character on the line ('?').
The float conversion fails again on the third input line, and the corresponding variable is left untouched, and you fail to detect this condition by ignoring the return value of scanf().
Long story short:
Each getchar() call consumes a character that cannot be read by scanf() anymore.
Any scanf() call that ignores the return value is a bug. Without checking that, you cannot know that you actually read anything.
Btw: man scanf and man getchar could have told you everything I just said. It pays off to know how to read manpages.
In this case, it's best to first retrieve the user input as char* (fgets-like) and then parse it with sscanf (not scanf, sscanf).
You will have to check the return value of sscanf in order to know wether the input user is correctly formatted.
If you need to check if there is not garbage value after the parsing (like "g 12345 45.6 garbagevalue"), you can add a %c after and check if the value have changed.
char letter;
int integerNumber;
double floatingNumber;
char end;
char *userInput = ...;
end = '\0';
if (sscanf(userInput, "%c %d %f%c", &letter, &integerNumber, &floatingNumber, &end) == 3 && end == '\0') {
// First form
} else {
end = '\0';
if (sscanf(userInput, "%c %d%c", &letter, &integerNumber, &end) == 2 && end == '\0') {
// Second form
} else {
// Error : Input not strictly "%c %d %f" or "%c %d"
}
}
Sound good to you ?
I wonder if it would be simpler to read in a block of data from the keyboard to a string from the keyboard and then analyse with sscanf as in the outline below
#define MAX_INPUT 100
char data_input[MAX_INPUT];
int finished=0, test;
char letter;
int num;
float value;
while (finished==0) {
// scanf("%s",data_input); //taken out after useful comments below
fgets(data_input,100,stdin); //replacement from comments...
// insert code using sscanf to read in data from user
test=sscanf(data_input, "%c %d %f", &letter, &num, &value);
if (test==3)
{
//success - sscanf successfully assigned 3 values...
// (ony if you have everything you need then....)
finished =1;
} else if (test==2){
// insert something to try to test if data from two data entries is ok....
// (ony if you have everything you need then....)
finished =1;
} else {
printf("problem with data entry - please type again\n");
}
}
with apologies to #Tom's because the use of sscanf was first suggested by him...

string modification taking input using get

I am trying to modify value of one string using other .
#include <stdio.h>
#include <string.h>
int main(void) {
char ch[10],s[3];
int c;
fgets(ch,10,stdin);
fgets(s,2,stdin);
c=(int)s[1];
ch[3]+=c;//s[1];
printf("%c\n",s[1]);
printf("%s",ch);
return 0;
}
Output is blank for s[1] and ch remains unchanged . However the program works fine if i remove the second gets and use a constant in place of c.
I would like to know the my error as well as the best simple approach for string manipulation .
EDIT : changed s[2] to s[3] , still same result
If the second fgets() read something (1 character), a terminating null character will be written to s[1].
Bits in terminating null character are all zero, and it means that the value of s[1] will become 0.
Adding zero means almost nothing.
You are running into a combination of issues. The first being if you are reading fgets(s,2,stdin); you get a maximum of 1 character in s plus the nul-terminating character. If you then take c=(int)s[1]; you are reading the second character of s into c. The second character of s will always be either '\n' (0xa hex, 10 decimal) if 1 character is entered or 0 (the nul-terminating char).
You run into your next problem with ch[3]+=c;. The result of which must fall within the printable range of characters. (see: asciitable.com ). That means if ch contains AAAA, the first character of s must have an ASCII value of 61 or less to remain in the printable character range.
Take the following example:
#include <stdio.h>
int main (void) {
char ch[10] = "",
s[3] = "";
int c = 0;
printf (" first input : ");
fgets (ch, 10, stdin);
printf (" second input: ");
fgets (s, 3, stdin);
printf ("\n you entered:\n first : %s second: %s\n", ch, s);
c = s[0];
ch[3] += c;
printf(" s[1] : %c\n",s[0]);
printf(" ch : %s\n",ch);
return 0;
}
Example Use
$ /bin/fgetsbasic
first input : HAHA
second input: !
you entered:
first : HAHA
second: !
s[1] : !
ch : HAHb
Anything with an ASCII value greater than 61 will cause you to fill the 4th character of ch with a non-printable value. (this changes depending on what the 4th char in ch originally is)

Why are the Elements of array not printing right?

I'm just starting out with C. I wrote some very basic code for practice, its supposed to read keyboard input into an array, output the length of longest line and then print it.
Theres a function to read the input, I want it to print out each character as it is assigned to the array each time, but it does not work. It prints some strange looking characters.
I did look for "array print garbage" . but didn't find an answer.
int getline(char line[])
/*
This function 1) Reads a line of input until a '\n',
2) Returns the length of the line and
3) Saves the line in the array "line[]"
*/
{
int c,i;
i=0; // The character count
printf("Enter characters:\n");
while((c=getchar())!='\n') // Reads input until it hits a '\n'
{
line[i]=c;
i++;
printf("char %d = %c \n ",i,line[i]);//
Why doesn't this "printf" work right? It prints a strange character at the second placeholder
}
printf("you typed %d characters.\n",i); //Outputs the number of characters typed
return i;
}
You're printing line[i] after you've incremented i. So you're always printing the element after the one you've just set, which is usually garbage.
Put the line
i++;
at the end of your while loop.

C Prints One Char More Without Value

I am trying to print the ASCII values of 3 char-type characters. When I input the first char it doesn't print the value of the char. After the first char it starts to give the value.
#include <stdio.h>
int main() {
char ch;
int t;
while(t < 3){
scanf("%c\n", &ch);
printf("%c - %d\n", ch,ch);
t++;
}
}
http://i54.tinypic.com/2mdqb7d.png
Variable t is not automatically initialized to 0 by compiler. So You need to initialize t with 0. If printf doesn't print immediately it means the data is buffered. If you want to see immediatley you may consider flushing stdout right after printf.
I saw this several times, and don't know the root cause, but solution that works is:
scanf("\n%c", &ch);
It probably has something to do with buffered end of line character.

Resources