I am experimenting with character input functions in C.Following is the program I am running interchanging getch and getche function calls for experimenting.
#include <stdio.h>
#include <conio.h>
#define MAX_CHARS 255
int main(){
//getche experiments
char buffer[MAX_CHARS+1],ch;
int x = 0;
while(x<MAX_CHARS&&(ch=getch())!='\r'){//relacing getch here with getche
buffer[x++]=ch;
putchar(ch);
}
buffer[x]='\0';
printf("%s",buffer);
return 0;
}
When I run the program with getch(),I get to see the each character
printed as soon as I enter them through keyboard(thanks to
putchar),and the whole line once I press enter(thanks to printf
statement at last).So it is fine.
When I replaced getch with getche the only difference I expected was
I would get each of the characters I enter printed twice as soon as I
enter(since getche echoes the character to stdout) and print the line
at last after I press enter.But as soon as I press enter whole screen
is cleared and the line is printed.
Why is the screen getting cleared before printing at last?
Thank you
There's no way for us to know without knowing what your documentation for getche says. There is no such standard function. My guess would be that it writes to a different screen from the one printf writes to. The screen is getting cleared because you have switched from one screen (the raw 'console' screen you echoed to) to another one (the normal terminal your program's standard output is attached to).
What does your platform's documentation for getche say?
Related
I am a new learner to the C language. I am trying to figure out how to use scanf. This is my code so far.
#include <stdio.h>
#include <string.h>
int main() {
char lastInitial;
printf("What is your last inital?");
scanf(" %c", &lastInitial);
}
When I run this code (I'm using VS Code), it shows that the file is running, but nothing shows up. When I go to the top to click the run button again, it says this code is already running. If I stop the run, delete the scanf line and run again, the file runs and displays "What is your last inital?" I am confused as to why adding scanf to the file stops the printf and doesn't allow any user input.
You might have run into a little intricacy with how printf works. When you run printf("What is your last inital?");, this text does not end with a newline (\n) character. As a result, some environments might not display it right away, delaying it until you printf a complete line or until the program ends. This is done for efficiency, since the internal steps to actually get output to your screen are a bit expensive.
When you remove the scanf, the program ends right after the printf; as the program is ending any text that's still waiting to be displayed gets sent to the screen by the built-in shutdown routines in the C standard library. However, when the scanf is included, the text gets buffered/delayed, and doesn't ever get sent to the screen sine the program is stalled waiting for user input. You can force the output to be sent immediately using a newline:
#include <stdio.h>
#include <string.h>
int main() {
char lastInitial;
printf("What is your last inital?\n");
scanf(" %c", &lastInitial);
}
Or if you don't want a newline, you can tell the C standard library to explicitly send all output text right away:
#include <stdio.h>
#include <string.h>
int main() {
char lastInitial;
printf("What is your last inital?");
fflush(stdout);
scanf(" %c", &lastInitial);
}
When you run the program, you should switch from "OUTPUT" to "TERMINAL".
You need to install the "Code Runner" extension.
Then go to File-->Preferences-->Settings in the search write code runner, and below will appear some settings of code runner, you need to find Run In Terminal, and turn it on.
THAT'S ALL :)
When you read from stdin using getchar, fgets or some similar function, if you type some text and then put an eof (control+d in linux) you cannot delete the previous text. For example, if I type 'program' and then enter eof by pressing control+d, I can't delete what I typed before, i.e. program.
#include<string.h>
#include<stdlib.h>
int main() {
char buffer[1024] = "";
printf("> ");
if(fgets(buffer,sizeof(buffer),stdin) == NULL){
puts("eof");
}
else{
puts(buffer);
}
return 0;
}
How can this be avoided?
The readline function of The GNU Readline Library I think is my best option to do the job. It's pretty simple to use but it uses dynamic memory to host the string so you have to use the free function to free up the memory. You can find more information by opening a terminal and typing 'man readline'.
The code would look like this:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <readline/readline.h>
int main() {
char *ptr = readline("> ");
if(!ptr){
puts("eof");
}
else{
puts(ptr);
}
free(ptr);
return 0;
}
To be able to use readline with gcc you must pass it -lreadline
When fgets reads a line, what will happen is that it will read characters from the specified stream until it encounters a '\n' or EOF, until it has read the specified maximum size to read or a read error occurs. It does not see what you are doing on your keyboard at all. It only sees the stream, but it is the terminal that sends the data to the stream.
What's happening when you are editing the input has absolutely nothing to do with fgets. That's the terminals job.
As Eric Postpischil wrote in the comments:
Pressing control-D in Linux does not signal EOF. It actually means “Complete the current read operation.” At that point, if characters have been typed, they are immediately sent to the program, whereas the system would usually wait until Enter is pressed. If no characters have been typed, the read operation completes with zero characters read, which some I/O routines treat as an EOF, and that is why programs may seem to receive an EOF when control-D is pressed at the start of a line of input. Since the data is sent to the program, of course there is no way to undo it—it has already been sent.
I guess there is some way to alter the behavior of pressing C-d, but then you need to decide what it should do instead. If you want it to do "nothing" instead of sending the data to stdin I cannot really see what you have won. The only use case I can see with this is if you for some reason are having a problem with accidentally pressing C-d from time to time.
One thing you could do is to take complete control of every keystroke. Then you would have to write code to move the cursor every time the user presses a key, and also write code to remove characters when the user is pressing backspace. You can use a library like ncurses for this.
It can't be avoided. Simply put, Ctrl+D ends the current read operation.
If you want to ignore this, make your own fgets based on fgetc and have it ignore end-of-file.
#include <stdio.h>
#include <conio.h>
#define ENTER_KEY '\n'
#define NULL_TERMINATOR '\0'
int main()
{
char name[100], input;
int counter = 0;
while(input != ENTER_KEY)
{
input = getchar();
name[counter] = input;
counter++;
}
counter--;
name[counter] = NULL_TERMINATOR;
printf("%s", name);
return 0;
}
If I write something, it should continuously saved in the name Array. And the counter should go up on every character I enter. But if I press Backspace, it looks like it makes the counter decreased. Because for example if I write "abcdef" and press backspace 3 times and change that to "abcxyz", and then press Enter. It prints "abcxyz".
It depends on the console driver. On most systems (at least Unix-like in line mode and in Windows console), the program does not receive the characters at the moment they are typed but the system prepares a line (up to the newline character) and sends the full line to the program.
In that case, the backspace if often used to edit that console buffer, meaning that the characters erased are actually removed before being handed to the program. So if you type abcdef<backspace><backspace><backspace>xyz<Return> the program will receive the following string: "abcxyz\n".
Beware, in a GUI program or in fullscreen text mode program like emacs or vi, the system is in raw mode (Unix language) and each character is received when it is typed. In that case, the program has to manage the input and erase its own character array when it receives a <backspace>.
I know it is a simple question but I am stuck.The code is:
#include <stdio.h>
#define MAX_SIZE 1025
#define NUM 64
int main(){
int mem_size;
char types[NUM];
char values[MAX_SIZE];
fgets(types,NUM,stdin);
printf("%s",types);
fgets(values,MAX_SIZE,stdin);
printf("%s",values);
scanf("%d",&mem_size);
printf("%d",mem_size);
return 0;
}
Although I want the results after I type and hit enter, the flow is: I need to enter all the fgets and scanf stuff and it correctly prints the desired results.
What is the problem? Please help.
OP: "Problem is it shows the results after I enter mem_size altogether simultaneously, not one by one"
Some systems to not "flush" the stdout output promptly even with a \n. The output that was seen came out just before the program ended, which forced the buffered stdout to the console.
Either add fflush(stdout) after each printf() or change your system's settings (varies with environment) to promptly send stdout to the console.
Ref:
printf not printing on console
I'm starting to learn C now and i'm trying to figure out how I would go about capturing when the user hits "enter." I'm looking particularly at the scanf and getc functions but I'm not quite sure how to go about it. When the user hits enter I want to perform some operations while waiting/watching for him to hit enter again... Is "enter" a new line character coming in from the console? Any advice would be much appreciated!
You can check the ascii value using fgetc().
while(condition) {
int c = fgetc(stdin);
if (c==10) {//Enter key is pressed
//your action
}
}
If you just need the input when user presses enter as input you can use scanf or getchar. Here is an example from cplusplus.com
/* getchar example : typewriter */
#include <stdio.h>
int main ()
{
char c;
puts ("Enter text. Include a dot ('.') in a sentence to exit:");
do {
c=getchar();
putchar (c);
} while (c != '.');
return 0;
}
This code prints what you entered to stdin (terminal window).
But if you do not want the input ( i know it's really unnecessary and complicated for a new learner) you should use an event handler.
printf("Hit RETURN to exit"\n");
fflush(stdout);
(void)getchar();
Ref: comp.lang.c FAQ list · Question 19.4b
The C language is platform-independent and does not come with any keyboard interaction on its own. As you are writing a console program, it is the console that processes the keyboard input, then passes it to your program as a standard input. The console input/output is usually buffered, so you are not able to react to a single keypress, as the console only sends the input to the program after each line.
However! If you do not demand your console application to be platform-independent, there is a non-standard library <conio.h> in some Windows compilers that has a function called getche();, which does exactly what you want - wait for a single keypress from the console, returning the char that was pressed.