I use CLION as my IDE.
I have the following code snippet which is suppose to reverse lines of user input in STDIN.
void reverse(){
char str1[100];
fgets(str1, 100, stdin);
printf("%s", str1);
}
Now when I hit Ctrl+D on my machine it prints out ^Z in STDOUT.
I am trying to make, that fgets() reads each line until the user hits EOF key, how would I do this in C?
I hit Ctrl+D this registers as ^D to stdin
and the printf statement prints out ^Z.
Related
I have the following C code in code.c
int main(int argc, char *argv[]) {
FILE *openFile = NULL;
openFile=stdin;
}
but when I compile and run my code with
gcc -g -o compiledcode code.c
./compiledcode
the terminal doesn't prompt me for an input. What is wrong?
You just open stdin as file but you don't read your file.
There are many different ways to get input from stdin.
Function getchar can be used to read a single character from stdin. Use getc() or fgetc() to read from an arbitrary file stream.
Example:
int c = getchar();
printf("you entered %c\n", c);
Function fgets can be used to read a line from file.
Example:
char data[200];
fgets(data, sizeof(data), stdin); // we type stdin as file.
printf("you entered %s\n", data);
Function scanf and its family of functions can be used to read many different formats from stdin.
example:
char data[200]; // size need be bigger or equal to input length
scanf("%199s", data); // Protect from buffer overflow
printf("you entered %s\n", data);
I have a multi-threaded application and am trying to format my output in the terminal with escape codes. The only issue I am having is that when gathering input, I cannot place an output mutex around fgets since it will block output until something is input. Consequently, there is this small window where other threads gain access to the output mutex and print before I can erase the newline created by fgets with \b.
Is there a way around this? Or is there a function in C that accepts input without entering a newline after pressing ENTER?
My code for input is as follows:
pthread_mutex_lock(&mutex_stdout);
fflush(stdout);
printf("\33[2K\r");
printf("Accept input: ");
fflush(stdout);
pthread_mutex_unlock(&mutex_stdout);
memset(buffer, 0, BUFFER_SIZE);
fgets(buffer, BUFFER_SIZE, stdin);
pthread_mutex_lock(&mutex_stdout);
buffer[strcspn(buffer, "\r\n")] = 0;
printf("\b");
pthread_mutex_unlock(&mutex_stdout);
If I were to print a prompt to stdout:
printf("> ");
and then I said
fgets(tester, 80, stdin);
would fgets read the whole line including the "> " or would it start after that?
The prompt is output (on stdout). fgets is reading input from stdin. So no, it won't read your prompt.
Your terminal displays stdout, stderr and stdin all together, but that doesn't mean there isn't an underlying distinction between them.
stdout is typically line buffered, and printf("> "); lacks a new line, so the output may not appear on a terminal display until later. fflush(stdout) to insure it is outputted before the fgets().
printf("> ");
fflush(stdout);
fgets(tester, 80, stdin);
The fgets won't read anything because the printf will write on STDOUT and not on STDIN.
No. printf will reflect the stdout. It will never effects your stdin. The str buffer will reflect all the characters you give as an input after >.
Test for the same can be done like this:
#include<stdio.h>
int main() {
char str[80];
printf(">");
if( fgets (str, 60, stdin)!=NULL )
{
puts(str);
}
return 0;
}
I am writing two c files that one is to write(by stdout) and another is read(by stdin).
But the read code is always hangs with read(), I have tried fread function but useless.
Can someone give advice?
Write example:
int main() {
char *a_string="Hello";
write(fileno(stdout), a_string, strlen(a_string)+1);
return 0;
}
Read example:
int main() {
char buffer[100];
read(fileno(stdin), buffer, 100-1);
printf("buffer=%s\n", buffer);
return 0;
}
The read code is always hangs with read(), I have tried fread function but useless.
This is because read and fread, unlike fgets and similar functions, do not quit reading when the user inputs a newline (presses Enter). It waits until EOF is read or until the specified bytes have been read.
To send EOF to read you must press Ctrl+D.
You need to input the EOF to stop, in Linux,it's Ctrl+D.
Code:
#include <stdio.h>
#define NEWLINE '\n'
#define SPACE ' '
int main(void)
{
int ch;
int count = 0;
while((ch = getchar()) != EOF)
{
if(ch != NEWLINE && ch != SPACE)
count++;
}
printf("There are %d characters input\n" , count);
return 0;
}
Question:
Everything works just fine, it will ignore spaces and newline and output the number of characters input to the screen (in this program I just treat comma, exclamation mark, numbers or any printable special symbol character like ampersand as character too) when I hit the EOF simulation which is ^z.
But there's something wrong when I input this line to the program. For example I input this: abcdefg^z, which means I input some character before and on the same line as ^z. Instead of terminating the program and print out total characters, the program would continue to ask for input.
The EOF terminating character input only works when I specify ^z on a single line or by doing this: ^zabvcjdjsjsj. Why is this happening?
This is true in almost every terminal driver. You'll get the same behavior using Linux.
Your program isn't actually executing the loop until \n or ^z has been entered by you at the end of a line. The terminal driver is buffering the input and it hasn't been sent to your process until that occurs.
At the end of a line, hitting ^z (or ^d on Linux) does not cause the terminal driver to send EOF. It only makes it flush the buffer to your process (with no \n).
Hitting ^z (or ^d on Linux) at the start of a line is interpreted by the terminal as "I want to signal EOF".
You can observe this behavior if you add the following inside your loop:
printf("%d\n",ch);
Run your program:
$ ./test
abc <- type "abc" and hit "enter"
97
98
99
10
abc97 <- type "abc" and hit "^z"
98
99
To better understand this, you have to realize that EOF is not a character. ^z is a user command for the terminal itself. Because the terminal is responsible for taking user input and passing it to processes, this gets tricky and thus the confusion.
A way to see this is by hitting ^v then hitting ^z as input to your program.
^v is another terminal command that tells the terminal, "Hey, the next thing I type - don't interpret that as a terminal command; pass it to the process' input instead".
^Z is only translated by the console to an EOF signal to the program when it is typed at the start of a line. That's just the way that the Windows console works. There is no "workaround" to this behaviour that I know of.