I have a c program and I ask for the user input twice during my program. The first time the input function (my own) worked perfectly, but the second time the getchar() function seemingly doesn't run. I have looked into the problem myself and I found something related to trailing characters, but I'm still confused on my problem. I've tried to create a second function where the function keeps asking for input if the input given is a \n, and I've also tried using an extra getchar() function to get rid of the stored character in the input stream (I still don't fully understand this either). I've also tried other things, but they were involving my larger structures but not the getchar() function itself
My input function:
int getInput(char s[])
{
char c;
int i = 0;
while((c = getchar()) != EOF){
s[i] = c;
i++;
}
return i;
}
My main function:
main()
{
printf("Enter a string to convert: \n");
char s[1000];
int len = getInput(s);
char t[1000];
printf("Press 1 to convert from escape to real, or 2 to convert from real to escape: ");
char a[1];
getInput(a);
printf("%d\n", a[0]);
if(a[0] == '1') {
real(s, t, len);
} else if (a[0] == '2') {
escape(s, t, len);
} else {
printf("\nRestart the program and enter a 1 or a 2\n");
exit(0);
}
printf("\n%s\n", t);
}
Thank you
Actually your first getInput doesn't work as you would expect it to worked. Indeed this is where your program gets stuck because getchar still waits for an input.
When writing the input in your terminal and pressing Enter you fill the buffer of stdin and then you empty that buffer with your getchar.
Now let's say you write hello and then press Enter, so now you buffer is filled with hello\n (because when you press Enter, the newline is also put into the buffer).
Now your getchar will consume each and every letter until there is nothing left in your buffer. At this point I guess you though that getchar would return an EOF because there is nothing left to read but do not forget that when there is nothing to read getchar just waits for you to input something just like scanf.
So now you're trapped in a loop, you fill your input, it gets read, then you have to fill another input and you never leave the loop.
A solution would be to change your loop condition to stop when getchar returns the \n (because remember it also gets added into the buffer), so at this point the buffer would be empty, your string would be correct and your function would return.
Related
How can i use scanf to read string with blank space(without enter)? And i also want this program to stop whenever input is EOF.
I used the following code:
int main() //this is not the whole program
{
char A[10000];
int length;
while(scanf(" %[^\n]s",A)!=EOF);
{
length=strlen(A);
print(length,A);
//printf("HELLO\n");
}
return 0;
}
But it is reading two EOF(ctrl+Z) to stop the program.can anyone give me any suggestion?
it is reading two EOF(ctrl+Z) to stop the program
No. You may be pressing ^Z twice, yet scanf() is only "reading" one end-of-file EOF. That is just how your keyboard/OS interface works. Research how to signal end-of-file.
Other changes
char A[10000];
// while(scanf(" %[^\n]s",A)!=EOF);
// Drop final `;` (That ends the while block)
// Add width limit
// Compare against the desired result, 1, not against one of the undesired results, EOF
// Drop the 's'
while(scanf(" %9999[^\n]", A) == 1) {
length=strlen(A);
// print(length,A);
print("%d <%s>\n", length, A);
//printf("HELLO\n");
}
I have trouble finishing a while loop using '\0' in c programming language, the c code is the following
#include<stdio.h>
char r;
int main()
{
do
{
scanf("%c", &r );
printf("%c", r);
}
while (r!='\0');
return 0;
}
My problem is that the program never finishes at the final character of typed string line, the while loop is always in waiting mode because of the scanf and never go to return 0. I do not know why this happen.
The output of this program is like this:
1234
2345
4556
7788
2345, 4556, 7788
Those are numbers I typed, but the program never finish (never go to return 0), I want to print just one string and I want the program ends.
Typical user input is a line, a sequence of characters up to and including a final '\n'.
As a part of user input, '\0' is just another character. It is often difficult to key in. Some keyboards allow it with CtrlShift# or other ways #user3629249
Very rarely is a string (a sequence of characters up to and including a final '\0') used on input.
To handle user input, a simply approach is to use fgets() to read a line of user input. That input will be saved as a string by fgets(buf) by appending a null character '\0' to the characters read: all saved in buf.
#include<stdio.h>
int main(void) {
char buf[100];
if (fgets(buf, sizeof buf, stdin) == NULL) {
puts("End-of-file or error encountered");
} else {
// maybe lop off the potential trailing \n from buf
buf[strcspn(buf, "\n")] = '\0';
printf("User input was <%s>\n", buf);
}
return 0;
}
To end user input, the usual approach is to signal the "end-of-file", see recognise return as EOF on the console
If code must use scanf();, check the return value to detect end-of-file or input error. #user3629249
if (scanf("%c", &r ) != 1) {
puts("End-of-file or error encountered");
}
I was trying to search for an answer for that but couldn't, hope someone can help.
I have the following snippet of code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char c = '\0';
int error = scanf(" %c", &c);
// The user types now the following: A54fG6
while (error != EOF) {
printf("%c", c);
error = scanf(" %c", &c);
}
return 0;
}
Where the first comment is, the input buffer points at A. Then it goes into the while loop, prints the character 'A' and the second scanf advances the input buffer to point at 5. After the last iteration, when the printf printed '6' - the second scanf points at what character?
Or in different words, how can I know when the program finished reading the current input buffer and then do something before the scanf prompts the user for more characters?
First of all, scanf is a function. It points to some code, that runs every time you call it. Not to a character.
The input buffer of scanf is stdin (at least in your case), and it is open while the program is running. Whenever you call scanf, it tries to read from stdin. If it has nothing to read, it asks the user to input something. That's the way it works.
Now, the user may introduce an EOF character, but I don't think this is what you want.
My objective is to change the delimiter of scanf to "\n".
I tried using scanf("%[^\n]s",sen); and works fine for single inputs.
But when i put the same line inside a for loop for multiple sentences it gives me garbage values.
Does anyone know why?
Here's my code:
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]s",sen);
printf("%s\n",sen);
}
Consider this (C99) code:
#include <stdio.h>
int main(void)
{
char buffer[256];
while (scanf("%255[^\n]", buffer) == 1)
printf("Found <<%s>>\n", buffer);
int c;
if ((c = getchar()) != EOF)
printf("Failed on character %d (%c)\n", c, c);
return(0);
}
When I run it and type in a string 'absolutely anything with spaces TABTABtabs galore!', it gives me:
Found <<absolutely anything with spaces tabs galore!>>
Failed on character 10 (
)
ASCII (UTF-8) 1010 is newline, of course.
Does this help you understand your problem?
It works in this case (for a single line) but if I want to take multiple lines of input into an array of arrays then it fails. And I don't get how scanf returns a value in your code?
There are reasons why many (most?) experienced C programmers avoid scanf() and fscanf() like the plague; they're too hard to get to work correctly. I'd recommend this alternative, using sscanf(), which does not get the same execration that scanf() and fscanf() do.
#include <stdio.h>
int main(void)
{
char line[256];
char sen[256];
while (fgets(line, sizeof(line), stdin) != 0)
{
if (sscanf(line, "%255[^\n]", sen) != 1)
break;
printf("Found <<%s>>\n", sen);
}
int c;
if ((c = getchar()) != EOF)
printf("Failed on character %d (%c)\n", c, c);
return(0);
}
This reads the line of input (using fgets() which ensures no buffer overflow (pretend that the gets() function, if you've heard of it, melts your computer to a pool of metal and silicon), then uses sscanf() to process that line. This deals with newlines, which are the downfall of the original code.
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]s",sen);
printf("%s\n",sen);
}
Problems:
You do not check whether scanf() succeeded.
You leave the newline in the buffer on the first iteration; the second iteration generates a return value of 0 because the first character to read is newline, which is the character excluded by the scan set.
The gibberish you see is likely the first line of input, repeated. Indeed, if it were not for the bounded loop, it would not wait for you to type anything more; it would spit out the first line over and over again.
Return value from scanf()
The definition of scanf() (from ISO/IEC 9899:1999) is:
ยง7.19.6.4 The scanf function
Synopsis
#include <stdio.h>
int scanf(const char * restrict format, ...);
Description
2 The scanf function is equivalent to fscanf with the argument stdin interposed
before the arguments to scanf.
Returns
3 The scanf function returns the value of the macro EOF if an input failure occurs before
any conversion. Otherwise, the scanf function returns the number of input items
assigned, which can be fewer than provided for, or even zero, in the event of an early
matching failure.
Note that when the loop in my first program exits, it is because scanf() returned 0, not EOF.
%[^\n] leaves the newline in the buffer. %[^\n]%*c eats the newline character.
In any case, %[^\n] can read any number of characters and cause buffer overflow or worse.
I use the format string %*[^\n]%*c to gobble the remainder of a line of input from a file. For example, one can read a number and discard the remainder of the line by %d%*[^\n]%*c. This is useful if there is a comment or label following the number, or other data that is not needed.
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]s",sen);
printf("%s\n",sen);
getchar();
}
Hope this helps ... actually "\n" remains in stream input buffer... Ee need to flush it out before scanf is invoked again
I know I am late, but I ran into same problem after testing C after a long time.
The problem here is the new line is considered as input for next iteration.
So, here is my solution, use getchar() to discard the newline the input stream:
char s[10][25];
int i;
for(i = 0; i < 10; i++){
printf("Enter string: ");
scanf("%s", s[i]);
getchar();
}
Hope it helps :)
While using scanf("%[^\n]", sen) in a loop, the problem that occurs is that the \n stays within the input buffer and is not flushed. As a result next time, when the same input syntax is used, it reads the \n and considers it as a null input. A simple but effective solution to address this problem is to use:
char sen[20];
for (i=0;i<2;i++)
{
scanf("%[^\n]%*c",sen);
printf("%s\n",sen);
}
%*c gets rid of the \n character in the input buffer.
If I want to receive a one character input in C, how would I check to see if extra characters were sent, and if so, how would I clear that?
Is there a function which acts like getc(stdin), but which doesn't prompt the user to enter a character, so I can just put while(getc(stdin)!=EOF);? Or a function to peek at the next character in the buffer, and if it doesn't return NULL (or whatever would be there), I could call a(nother) function which flushes stdin?
Edit
So right now, scanf seems to be doing the trick but is there a way to get it to read the whole string, up until the newline? Rather than to the nearest whitespace? I know I can just put "%s %s %s" or whatever into the format string but can I handle an arbitrary number of spaces?
You cannot flush the input stream. You will be invoking undefined behavior if you do. Your best bet is to do:
int main() {
int c = getchar();
while (getchar() != EOF);
return 0;
}
To use scanf magic:
#include <stdio.h>
#include <stdlib.h>
#define str(s) #s
#define xstr(s) str(s)
#define BUFSZ 256
int main() {
char buf[ BUFSZ + 1 ];
int rc = scanf("%" xstr(BUFSZ) "[^\n]%*[^\n]", buf);
if (!feof(stdin)) {
getchar();
}
while (rc == 1) {
printf("Your string is: %s\n", array);
fflush(stdout);
rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getchar();
}
}
return 0;
}
You can use getline to read a whole line of input.
Alternatively (in response to your original question), you can call select or poll on stdin to see if there are additional characters to be read.
I had a similar problem today, and I found a way that seems to work. I don't know the details of your situation, so I don't know if it will work for you or not.
I'm writing a routine that needs to get a single character from the keyboard, and it needs to be one of three specific keystrokes (a '1', a '2', or a '3'). If it's not one of those, the program needs to send and error message and loop back for another try.
The problem is that in addition to the character I enter being returned by getchar(), the 'Enter' keystroke (which sends the keystroke to the program) is saved in an input buffer. That (non-printing) newline-character is then returned by the getchar() facility in the error-correction loop, resulting further in a second error message (since the newline-character is not either a '1', a '2', nor a '3'.)
The issue is further complicated because I sometimes get ahead of myself and instead of entering a single character, I'll enter the filename that one of these options will request. Then I have a whole string of unwanted characters in the buffer, resulting in a long list of error messages scrolling down the screen.
Not cool.
What seems to have fixed it, though, is the following:
c = getchar(); // get first char in line
while(getchar() != '\n') ; // discard rest of buffer
The first line is the one that actually uses the character I enter. The second line disposes of whatever residue remains in the input buffer. It simply creates a loop that pulls a character at a time from the input buffer. There's no action specified to take place while the statement is looping. It simply reads a character and, if it's not a newline, goes back for the next. When it finds a newline, the loop ends and it goes on to the next order of business in the program.
We can make a function to clear the keyboard buffer, like this:
#include <stdio.h>
void clear_buffer(){
char b;
//this loop take character by character in the keyboard buffer using
//getchar() function, it stop when the variable "b" was
//enter key or EOF.
while (((b = getchar()) != '\n') && (b != EOF));
}
int main()
{
char input;
//get the input. supposed to be one char!
scanf("%c", &input);
//call the clearing function that clear the buffer of the keyboard
clear_buffer();
printf("%c\n",input); //print out the first character input
// to make sure that our function work fine, we have to get the
// input into the "input" char variable one more time
scanf("%c", &input);
clear_buffer();
printf("%c\n",input);
return 0;
}
Use a read that will take a lot of characters (more than 1, maybe 256), and see how many are actually returned. If you get more than one, you know; if you only get one, that's all there were available.
You don't mention platform, and this gets quite tricky quite rapidly. For example, on Unix (Linux), the normal mechanism will return a line of data - probably the one character you were after and a newline. Or maybe you persuade your user to type ^D (default) to send the preceding character. Or maybe you use control functions to put the terminal into raw mode (like programs such as vi and emacs do).
On Windows, I'm not so sure -- I think there is a getch() function that does what you need.
Why don't you use scanf instead of getc, by using scanf u can get the whole string.