Scanning a single char into an array C Programming - c

I am having a problem scanning chars into an array. Every time I do it will skip the next scan and go to the next. I know what is happening because the input also adds '\n' to the input but I do not know how to remedy the cause of it. Here is some sample code:
char charray [MAX], ffs;
int inarray [MAX], i;
for (i = 0; i < MAX; i++)
{
charray[i] = getchar();
printf ("%c\n",charray[i]);
scanf ("%d", &inarray[i]);
printf ("%d\n",inarray[i]);
}

You can do like this.
while((c = getchar()) != '\n')
{
putchar(c);
}
this may solve your problem. or you can go till EOF also.

You are reading from the standard input with 2 functions: getchar() and scanf(). You need to understand how they work.
getchar() is easy: it returns the next available character in the input stream (or waits for one or returns EOF)
scanf("%d", ...) is more complex: first, it optionally discards whitespace (spaces, enters, tabs, ...), then it reads as many characters as possible to represent an integer, and stops at the first character that can't be used for integers, like a '\n'.
As you have them in a loop, your getchar() call will get the character that stopped the scanf() and the next scanf() will procedd from there.
If your input is something like "q1w22e333r4444" (with MAX == 4), your program will work.
If your input is something like
q 1
w 22
e 333
r 4444
after the first time through the loop (where charray[0] gets 'q' and inarray[0] gets 1), the getchar() will get '\n' leaving the 'w' "ready" for scanf, which of course fails ... and is then "caught" by the next getchar(); and the "22" gets assigned in the 3rd time through the loop (to inarray[2]).
So, you need to review your code.
Also, scanf() returns a value. Use that value
if (scanf("%d", &inarray[i]) != 1) /* error */;

You should actually scan a string into the array directly, rather than characters using scanf("%s",&charray);
However your code will work if you add a while(getchar() != '\n' ); statement. This will get all characters till the '\n'.
charray[i] = getchar();
do{
c = getchar();
}while(c != '\n' && c!= EOF);
printf ("%c\n",charray[i]);
scanf ("%d", &inarray[i]);
do{
c = getchar();
}while(c != '\n' && c!= EOF);
printf ("%d\n",inarray[i]);

Related

Undefined behaviour of scanf() in a do-while loop

I'm currently learning C by a book "C Programming a modern approach" and encountered this code. When I tried to run it, after typing consecutive characters like 'abc' and hitting Enter (new line), nothing was printed. Please explain what is going on here.
char ch;
do {
scanf("%c" , &ch);
} while (ch != '\n');
printf("%c", ch);
You're asking the user to input a character using scanf. This is happening in a loop until the user inputs a '\n' or newline character (the same as pressing the enter key), which is when the loop will break.
Your print statement will then print the character in the variable ch, which at that point will be '\n' (since this variable just stores one character, the last one you typed).
This newline character will probably be invisible when you run your program so you may not be seeing it. You can add another print statement after the loop and if that print statement starts at a newline, you know that the '\n' was printed on the previous line.
Something like:
#include <stdio.h>
int main()
{
char ch;
do
{
scanf("%c" , &ch);
} while (ch != '\n');
printf("%c", ch);
printf("I should show up on a newline");
return 0;
}
The code you provided reads characters from the input using the scanf() function and stores them in the variable ch until a newline character (\n) is encountered. After that, the program prints the last character that was read, which is the newline character.
The reason you are not seeing any output when you enter characters followed by a newline character is because the printf() statement is only executed after the loop has finished running. So, the program is waiting for you to enter a newline character to terminate the loop and print the last character that was read.
If you want to see the characters you enter, you can add a printf() statement inside the loop, like this:
char ch;
do {
scanf("%c" , &ch);
printf("%c", ch);
} while (ch != '\n');
This will print out each character as it is read from the input, so you can see what you're typing. Happy coding :)
When I tried to run it, after typing consecutive characters like abc and hitting Enter (new line), nothing was printed.
Well with the posted code, if the loop even finishes, the last byte read by scanf("%c", &ch) and stored into ch is the newline character. Hence printf("%c", ch) outputs this newline and it seems nothing is printed but something is, the newline which is invisible on the terminal but does move the cursor to the next line.
You can make this more explicit by changing the printf call to this:
printf("last value: '%c'\n", ch);
Note however that the posted code is not a recommended way to read the contents of the input stream:
scanf("%c", &ch) may fail to read a byte if the stream is at end of file. Failure to test this condition leads to undefined behavior (ch is unmodified, hence stays uninitialized if the input stream is an empty file) or to an infinite loop as ch may never receive a newline.
this code is a typical example of a do / while with a classic bug. It would be much better to write the code using getchar() and a while loop.
Here is a modified version:
#include <stdio.h>
int main(void) {
int c; // must use int to distinguish EOF from all valid byte values
int count = 0; // to tell whether a byte was read at all
char ch = 0; // the last byte read
// read all bytes from the input stream until end of file or a newline
while ((c = getchar()) != EOF && c != '\n') {
ch = (char)c;
count++;
}
if (count == 0) {
printf("no characters entered: ");
if (c == EOF) {
printf("end of file or read error\n");
} else {
printf("empty line\n");
}
} else {
printf("last character on line is '%c'\n", ch);
if (c == EOF) {
printf("end of file or input error encountered\n");
}
}
return 0;
}

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;
}

Do scanf and getchar handle stream differently?

I'm confused about how scanf and getchar handle stream differently, the following is a sample code:
while(scanf("%d", &input) != 1)
{
while((ch = getchar()) != '\n')
{
putchar(ch);
}
printf("\nThis is wrong\n");
}
printf("That is right\n");
It is a simple program used to test if the input is a integer. The inner while loop is used to display every wrong input value before click Enter. When I entered a random string such as:
qwert
putchar will print out the exact string. However, if I replaced
while(scanf("%d", &input) != 1)
with
while((ch = getchar()) != '\n')
and print out the exact same string, the first letter "q" is dropped out.
So my question is how do scanf and getchar in the outer loop handle this situation differently?
When you use scanf to try and read an integer, and you give some input that is not an integer, then scanf will fail and not return 1. It will however leave the input intact, it won't extract anything from the input, leaving it all for your inner loop to digest and print.
If you use getchar in the outer loop, it will actually consume a single character, no matter what character it is, and the inner loop will then not see that character since it doesn't exist in the input buffer anymore.

While loop in C don't break even after encountering a NULL character

here is the code to add the numbers present in an Alphanumeric string :
#include<stdio.h>
#include<stdlib.h>
int main()
{
int total=0;
char ch;
printf("enter the string\n");
ch=getchar();
while(ch!='\0')
{
printf("I am here !!");
if (!(isalpha(ch)))
total+=(int)ch;
ch=(char)getchar();
printf("I am here !!");
}
printf("\ntotal is %d",total);
return 0;
}
No matter what characters I input , it gives 4 " I am here " for each character.
I tried to use
while((ch=getchar())!='\0');
but it gives the same problem .
getchar does not return '\0' at the end of the input: it is not reading from a null-terminated C string, but from a console, file, or some other stream.
When no additional input is available, getchar returns EOF. That is the condition you should be checking to decide when to stop your loop.
Stack Overflow offers many good examples of how to implement a loop reading getchar (link#1; link#2; please note the data types used in the examples).
The reason it doesn't work is because '\0' cannot be inserted from the keyboard, so getchar() is unlikely to be able to return '\0', a correct way of testing for the end of input would be
int ch;
while (((ch = getchar()) != EOF) && (ch != '\n'))
This is because EOF means, that the user intentionally wanted to stop entering data, and '\n' is usually the last thing that will be seen when stdin is flushed, since it triggers the flushing.

C : How to check end of input from keyboard or file while using scanf one char at a time

I have to write a program in C for class that reads in one character at a time and we have to use scanf. I got it to work with input from only the keyboard however, my teacher will be testing the code with file redirection as well.
int end; //return value of scanf
int length1; //length of string exp1
char temp, //temp char for input
char exp1[81]; //string
printf ("Please enter in a regular expression:\n");
end = scanf ("%c", &temp);
while (temp != '\n' || end == 1) { //check if end of input
length1 = check(temp, length1, exp1); //returns length of exp1
end = scanf ("%c", &temp); //scan next char for loop
}
I've been at this one tiny problem for hours trying to figure it out so any pointers are helpful. Thanks!
EDIT: I've tried using the kbhit() function in an if statement to check if they typed in the input or if the input is from a file. However, I don't have conio.h, is there any alternative while still using scanf?
Your narrower-scope question has already been answered, but let me give you a piece of good advice. If you are not forced to use scanf() in class (i. e. you are writing real, production code), then
Just get rid of scanf(). It's evil. It does not do what you think it does.
If you want to get one character at a time, then use the function that gets one character at a time. And that is fgetc(stdin).
int c;
while ((c = fgetc(stdin)) != EOF) {
/* process `c' */
}
scanf returns EOF if an input failure occurs before the first conversion (if any) has completed. So you may check on that. But you only read one character each time, that doesn't seem necessary since you already check if the return value if 1.
I think the error is in the logic in your while condition, it should be:
while (temp != '\n' && end == 1)
// ^^
You need to compare scanf output with EOF
while(scanf("%c", &temp) != EOF)
{
}
You could convert this to something like:
do{
length1 = check(temp, length1, exp1); //returns length of exp1
end = scanf ("%c", &temp); //scan next char for loop
}while (temp != '\n' && end != EOF) ;

Resources