Converting char to Int with getchar() extra numbers - c

I want to convert a char to an int. However when I use the usual way of
convertedInt = c - '0';
I get an extra negative number when printing the results. For instance this code with the input 654 produces the output:
while (c != '\n'){
c = getchar();
convertedInt = c - '0';
printf("%d\n", convertedInt);
}
//Output
4
5
6
-38
I don't think it has anything to do with the getchar because if I just print the char without converting it I get the expected output.

You are testing before reading the character. Try this:
int c;
while ((c = getchar()) != '\n' && c != EOF) {
convertedInt = c - '0';
printf("%d\n", convertedInt);
}
Note that getchar() can return EOF in the event of an error, or if the user signals EOF from the keyboard, and so c should be tested for this value to avoid a possible infinite loop.
In the code from the question, it appears that the controlling expression of the while statement tests the value of c uninitialized the first time. This leads to undefined behavior. Later, when the last digit is read and printed, c is tested again and found not to be \n. Then getchar() is called and c has a value of 10, the decimal value of the newline character in ASCII. So, convertedInt gets the value 10 - 48, or -38. Then c is tested a final time; now it is equal to \n, and the loop is terminated.

First of all, getchar returns an int that normally contains a character code in the lowest byte. The reason that it returns an int is that it has to be able to return a value for EOF that is distinct from any possible unsigned char value. EOF is used to indicate the end of the input and is not meant to be treated like a character input. On many systems, EOF has the value -1.
The value you are seeing is '\n' - '0' == 10 - 48 in ASCII.
Here is a common idiom for handling the undesirable inputs from getchar():
while((c = getchar()) != EOF && c != '\n') {
if(c >= '0' && c <= '9') {
convertedInt = c - '0';
printf("%d\n", convertedInt);
}
}
A similar check can be acheived by including #include <ctype.h> and changing the condition of the if statement to if(isdigit(c)).

When you do getChar(), you are checking it for \n later, but you are subtracting '0' first. Replace with this
while(1){
c = getchar();
if(c == '\n')
break;
convertedInt = c - '0';
printf("%d\n", convertedInt);
}

Related

Why is it needed to give getchar() value of an integer variable in order to have putchar() print all characters?

I am learning C from the book "The C Programming Language";
my question is about something I observed while trying to reformulate with few lines of code regarding input and output:
why is it needed to give the getchar() function a value of a certain integer in order to have it store all the text in the input?
For example with this code putchar() is printing all that I type;
int c;
while ((c = getchar()) != EOF)
putchar(c)
But, why isn't it the same if I write:
while (getchar() != EOF)
putchar(getchar());
In the latter case, for example, if I write "okok", the program is then printing "kk".
I think the reason is within some property of getchar(), that I wasn't able to get;
for example, if I write a character counting program, and I want to exclude new lines, I also observed that it's working if I write it as:
int nc, c;
nc = 0;
while ((c = getchar()) != EOF)
if (c != '\n')
++nc;
printf("%d", nc);
But it's not able instead to distinguish correctly the '\n' when using getchar() directly instead of c integer:
while ((c = gethar()) != EOF)
if (getchar() != '\n')
++nc;
printf("%d", nc);
My purpose it is just to understand, as I wouldn't like to learn this just by memory, and in the book it is written that getchar() is working using int values, so I wonder if there is something that I missed about properties of getchar() despite reading several times, also searching in different questions in stack overflow regarding the getchar() topic.
When you write
while (getchar() != EOF)
putchar(getchar());
It always
reads one character and checks it for EOF,
reads one (another) character and prints it,
repeats.
Therefore, in your "okok" example, the odd 'o' characters are read, compared to EOF and discarded, and only the even 'k's make it through.
If you wanted to print all of the input characters, you would have to restructure your code. For example, to call getchar() once, save the return value to a variable, then use the already read value twice - check it for EOF and print it.
while (1) { /* loop forever (until break is called) */
int ch = getchar();
if (ch == EOF)
break;
putchar(ch);
}
getchar() function gets one char from the input and returns it.
while (getchar() != EOF)
putchar(getchar());
You have used the getchar() function two times.
For the input 'okok'
'o' will be returned in while (getchar() != EOF).
'k' will be returned in putchar(getchar());
Since you have written putchar() here it will get the char 'k' and prints it.
And again the process continues and prints only 'k'.
So the output will be 'kk'
To get the value 'okok' and print it try
do
{
char c=getchar();
if(c!=EOF)putchar(c);
}while(c!=EOF);

Don't know how to use getchar function correctly / C

I wanted to create a function that inputs a character in the console but the problem is that sometimes when I input 'a' it is considered as an empty char and the programm asks me to re-input a char.
This is the function :
char readChar()
{
char character;
character = getchar();
character = toupper(character);
while(getchar() != '\n' && getchar() != '\0');
return character;
}
Converting a barrage of comments into an answer.
1. Note that getchar() returns an int, not a char. And your loop needs to take into account EOF more than a null byte, though it's probably OK to detect null bytes.
My best guess about the trouble is that sometimes you do scanf("%d", &i) or something similar, and then call this function — but scanf() doesn't read the newline, so your function reads a newline left over by previous I/O operations. But without an MCVE (Minimal, Complete, and Verifiable Example), we can't demonstrate that my hypothesis is accurate.
2. Also, your 'eat the rest of the line' loop should only call getchar() once on each iteration; you call it twice. One option would be to use:
int readChar(void)
{
int c;
while ((c = getchar()) != EOF && isspace(c))
;
if (c == EOF)
return EOF;
int junk;
while ((junk = getchar()) != '\n' && junk != EOF /* && junk != '\0' */)
;
return toupper(c);
}
This eats white space until it gets a non-white-space character, and then reads any junk characters up to the next newline. It would fix my hypothetical scenario. Beware EOF — take EOF into account always.
Based on reading the Q&A about scanf() not reading a newline, Voltini proposed a fix:
char readChar()
{
char character;
scanf(" %c", &character);
getchar(); //I just added this line
character = toupper(character);
return character;
}
3. That is often a good way to work. Note that it has still not dealt with EOF — you always have to worry about EOF. The getchar() after the scanf() will read the newline if the user typed a and newline, but not if they typed a-z and then newline. You have to decide what you want done with that – and a character gobbling loop is often a good idea instead of the single getchar() call:
int c;
while ((c = getchar()) != EOF && c != '\n')
;
And in response to a comment along the lines of:
Please explain the importance of handling EOF.
4. If you don't ask, you won't necessarily learn about it! Input and output (I/O) and especially input, is fraught. Users don't type what you told them to type; they add spaces before or after what you told them to type; you expect something short like good and they type supercalifragilisticexpialidocious. And sometimes things go wrong and there is no more data available to be read — the state known as EOF or "end of file".
5. In the function with char character; scanf(" %c", &character); and no check, if there is no input (the user types ^D on Unix or ^Z on Windows, or the data file ended), you have no idea what value is going to be in the variable — it is quasi-random (indeterminate), and using it invokes undefined behaviour. That's bad. Further, in the code from the question, you have this loop, which would never end if the user indicates EOF.
while (getchar() != '\n' && getchar() != '\0') // Should handle EOF!
;
6. And, to add to the complexity, if plain char is an unsigned type, assigning to character and testing for EOF will always fail, and if plain char is a signed type, you will detect EOF on a valid character (often ÿ — small latin letter y with diaeresis in Unicode and 8859-1 or 8859-15 code sets). That's why my code uses int c; for character input. So, as you can see (I hope), there are solid reasons why you have to pay attention to EOF at all times. It can occur when you don't expect it, but your code shouldn't go into an infinite loop because of that.
I'm not sure how and where to … implement this … in my code.
7. There are two parts to that. One is in the readChar() function, which needs to return an int and not a char (for the same reasons that getchar() returns an int and not a char), or which needs an alternative interface such as:
bool readChar(char *cp)
{
int c;
while ((c = getchar()) != EOF && isspace(c))
;
if (c == EOF)
return false;
*cp = toupper(c);
while ((c = getchar()) != '\n' && c != EOF /* && c != '\0' */)
;
return true;
}
so that you can call:
if (readChar(&character))
{
…process valid input…
}
else
{
…EOF or other major problems — abandon hope all ye who enter here…
}
With the function correctly detecting EOF, you then have your calling code to fix so that it handles an EOF (error indication) from readChar().
Note that empty loop bodies are indicated by a semicolon indented on a line on its own. This is the way K&R (Kernighan and Ritchie in The C Programming Language — 1988) wrote loops with empty bodies, so you find it widely used.
You will find over time that an awful lot of the code you write in C is for error handling.
Do not read potentially twice per loop as with while(getchar() != '\n' && getchar() != '\0'); #Jonathan Leffler
To read a single and first character from a line of user input:
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. C11dr §7.21.2 2
Use getchar(). It returns an int in the range of unsigned char or EOF.
Read the rest of the line.
Sample code, a bit like OP's.
int readChar_and_make_uppercase() {
int ch = getchar();
if (ch != '\n' && ch != EOF) {
// read rest of line and throw it away
int dummy;
while ((dummy = getchar()) != '\n' && dummy != EOF) {
;
}
}
return toupper(ch);
}
Apparently, I forgot to take care of the newline character stored in the buffer (correct me if I'm wrong).
char readChar()
{
char character;
scanf(" %c", &character);
getchar(); //I just added this line
character = toupper(character);
return character;
}

c programing what is the meaning of this getchar and EOF and what this code do i didn't understand

count = 0;
while ( (c = getchar()) != EOF)
{
if (c != '\t' && c != '\n') continue;
if (c == '\n') break;
if (c == '\t') count++;
}
what is the code mean and the getchar and EOF mean I did not understand
The getchar() standard function reads a character from the standard input stream.
The returned value is of type int (which is "wider" than char) since it can also return EOF for when input reading failed, generally because the stream was closed. The token EOF in the code is simply a constant from the header, it can be declared like this:
#ifndef EOF
# define EOF (-1)
#endif
So it's literally just an alias for the integer literal -1 (but I don't think you can rely on the numerical value, use the symbolic name!).
The code loops until EOF is detected, i.e. it loops over all characters readable on its standard input stream, and counts the number of times \t is found.
It can be simplified a lot, the first if is pointless (and the continueis of course mis-spelled).

putchar and printf not behaving as expected

I'm working through some of the exercises in K&R. Exercise 1-6 asks for verification that the expression getchar() != EOF is either 0 or 1. I understand why it is, but the code I wrote to prove it didn't work as expected. I wrote the following two snippets:
Version 1:
int main(void)
{
int c;
while (c = getchar() != EOF)
{
putchar(c);
}
printf("%d at EOF\n", c);
return 0;
}
Version 2:
int main(void)
{
int c;
while (c = getchar() != EOF)
{
printf("%d\n", c);
}
printf("%d at EOF\n", c);
return 0;
}
My questions:
When I type in a character and hit enter with version one, why do I not see either a 0 or 1 on the screen? Instead, my cursor moves to the first position on next line, which is otherwise empty. I though putchar would send c to stdout.
While the use of printf in the second version does produce a 0 or 1 appropriately, it duplicates the 1 for each non-EOF character (I see the number 1 on two consecutive lines for each character I input). Why?
Many thanks in advance for your thoughts. If there is a reference that you think would help, please send a link.
CLARIFICATION:
I know I'm assigning c a value of either 0 or 1. That's what I want to do, and it's what the exercise wants. That's also why I don't have parentheses around c = getchar(). My question deals more with understanding why the output isn't what I had expected. Sorry for any confusion.
The assignment operator = has lower precedence than the inequality operator !=.
So this:
while (c = getchar() != EOF)
Is parsed as:
while (c = (getchar() != EOF))
So then c is assigned the boolean value 1 if getchar is not EOF and 0 if it does return EOF.
As a result, the first program print the character for the ASCII code 1, which is a non-printable character. That's why you don't see anything. The second program, using the %d format specifier to printf, converts the number 1 to its string representation.
You need parenthesis to have the result of getchar assigned to c:
while ((c = getchar()) != EOF)
EDIT:
To further clarify the output you're getting, in both programs the variable c has the value 1 inside of each while loop. The difference here is that putchar is printing the character with the ASCII value of 1 (an unprintable character), while printf with %d print the textual representation of the value 1, i.e. 1.
If you changed the printf call to this:
printf("%c", c);
You would get the same output as using putchar.
As for the printing of 1 twice for each character, that is because you're actually entering two characters: the key you press, plus the enter key. When reading from the console, the getchar function doesn't return until the enter key is pressed.

What does this not work for getchar() method?

This was my own experiment to understand what goes under the hood, what does this program mean to the compiler?
main()
{
int c;
printf("%d\n",c);
printf("%d ", getchar());
while ((c == getchar()) != EOF){
putchar(c);
}
}
When I say c must equal getchar() (c == getchar()), does it not proceed through the while loop? Now I am really confused of my own code, of what c must mean!
Also, in this code:
main()
{
int c;
c = getchar()
while ((c = getchar()) != EOF)
putchar(c);
}
if we modify the int c to int c = getchar(), why cannot we somply write like this:
while (c != EOF)(
putchar(c);
c = getchar();
}
The compiler should know from the previous statement that c = getchar(), why have to write the statement again? Sorry, if I am confused.
while ((c==getchar()) != EOF) {
...
}
is a while loop. It evaluates the condition for each iteration of the loop and terminates only if the condition is false.
In your case, the condition is:
(c==getchar()) != EOF)
which is a nonsensical expression, but let's examine it anyway:
First, the program will evaluate:
getchar()
This grabs a keystroke from standard input. The value of the expression is the value of the key.
Then:
c==getchar()
This takes the result of getchar() and compares it to whatever is currently in c. In your first program, c is uninitialized, so its value is indeterminate. If c had a defined value, then c==getchar() would evaluate to either true or false. Since c had no defined value, c==getchar() also has no defined value.
Now the program evaluates:
(c==getchar())
Which would still be true or false, except that in your case it is undefined.
The program next considers:
(c==getchar()) != EOF
That is, it compares the true-false value to EOF; this makes no particular sense, and in your case we still have the undefined behavior of an uninitialized c.
In sum, if c were initialized, the expression would fetch a key from standard input and then compare either true or false to EOF. As I said, it is a nonsensical expression.
You're saying you want to look under the hood? Great! Let's dive in :)
while ((c == getchar()) != EOF)
As others have noted, this should be while ((c = getchar()) != EOF). The reason you do assignment (=) rather than equality testing (==) is because you're actually rolling two lines of code into one: c = getchar(); and while(c != EOF). So if the current character being read is k, the program evaluates it in a way kind of like this:
while ((c = getchar()) != EOF)
while ((c = 'k') != EOF)
while (('k') != EOF)
while ('k' != EOF)
while (1) // true
And it has the convenient side effect that c still has k inside for whatever you're planning on doing.
The other problem is here:
int c;
printf("%d\n",c);
printf will complain because you don't have anything assigned to c yet. It's been "declared", but not "initialized." It can't print something that's not there - and if it can, it would surely print something you don't want.
You have an extra equal sign that you need to remove:
while ((c == getchar()) != EOF){
should be
while ((c = getchar()) != EOF){
Here is what is happening. When (c == getchar()) is executed, to begin with c is uninitialized, so it has some garbage value. That garbage value is compared to the next character in the input stream, to see if they are the same. The result of the comparison is going to be 0 (if they are different) or 1 (if they are same). The latter is very unlikely, but it is theoretically possible that by some lucky (?) chance, the garbage value does happen to match the next character in the input stream.
That 0 or 1 is then compared to see whether it matches EOF. Well, EOF is going to be some negative value; that's what it is by definition. Obviously 0 or 1 will never match any negative value, so your loop will be infinite.
As for your second code fragment:
c = getchar();
while ((c = getchar()) != EOF) {
You're not checking whether the first character is EOF, as the value of c after the first getchar() will be immediately replaced by the assignment in the while condition. Assuming that there is a non-EOF first character, your code will work.
As for your third code fragment:
c = getchar();
while (c != EOF) { // corrected your typo of ( instead of {
putchar(c);
c = getchar();
}
The reason why you have to write c = getchar() again inside your while loop is to update the value of c with the second and subsequent characters in the input stream. Otherwise, it will always compare the current value of c, which is the first character in the input stream, to EOF, and this too will be an infinite loop unless the first character does happen to be EOF.
The most concise way of accomplishing what you want is:
int c;
while ((c = getchar()) != EOF)
putchar (c);
... just like your second code fragment, minus the extra line that does the first getchar() and assigns it to c.
c == getchar() != EOF means
c == getchar() is true if c and the result returned from getchar() are the same.
c == getchar() will always be not equal to EOF (since neither true not false equals EOF) so the program should infinite loop printing the character that randomly showed up here since you never initialized c int c;.

Resources