Echo input into output, at the right place - c

I want to insert the input given to a program into its output, in the moment it is read.
For instance, given the program:
#include <stdio.h>
int main() {
double x, y;
printf("Soma de dois números:\n");
printf("Digite o primeiro número: ");
scanf("%lf", &x);
printf("Digite o segundo número: ");
scanf("%lf", &y);
double soma = x + y;
printf("%lf + %lf = %lf\n", x, y, soma);
return 0;
}
when it is run with input redirection, I want the input inserted into the output, like the following:
$ echo -e "10\n25\n" | ./a.out
sum of two numbers
first number: 12
second number: 25
12.000000 + 25.000000 = 37.000000
Is there any library or tool to help me with that?
Edited Context: I intend to use this for correcting program exercises in a programming course. I want to see/show the program input and output as if it were run in an interactive console with the input being typed interactively, although the input is redirect from a text file.

As I noted in a comment:
There isn't an easy way to do that. The problem is that when you type at the terminal, the terminal driver echoes the characters typed. When you have I/O redirection (from a pipe or a file), the terminal driver is not involved, and neither the disk driver nor the pipe driver echoes to standard output.
One option might be to use a pseudo-terminal for the input to your program — but I've not tried it so that might not work. It's also fairly fiddly to set up (though there might well be a utility available on Linux, in particular, to do the job).
Or you could test to see whether the input is a terminal, doing nothing special if it is a terminal, and echoing the result of the input if it is. POSIX function isatty() determines whether the given file descriptor is a terminal or not.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
printf("Enter a number: ");
double d;
if (scanf("%lf", &d) != 1)
{
fprintf(stderr, "Failed to read a number!\n");
exit(EXIT_FAILURE);
}
if (!isatty(STDIN_FILENO))
printf("%lf\n", d);
printf("You entered: %lf\n", d);
return 0;
}
With that saved as source file tty47.c, I can run:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -fno-common tty47.c -o tty47
$ tty47
Enter a number: 2.718282
You entered: 2.718282
$ echo "3.141593" | tty47
Enter a number: 3.141593
You entered: 3.141593
$ tty47 <<<'1.618034'
Enter a number: 1.618034
You entered: 1.618034
$
The first run accepts the input I type at the terminal, and that is echoed by the terminal driver. The other two runs know that the input comes from a pipe and a file respectively, and they echo the input. Note that the echo is not guaranteed to be exactly what the user entered — I cheated by typing numbers with 6 decimal places. Use fewer places and you get trailing zeros; use more and the result is rounded. You'll have to decide whether that matters.
An alternative strategy would read the input using getchar() or equivalent and echo each character with putchar() or equivalent if the input is not a terminal, and then use sscanf() to parse the data. That's definitely fiddlier.

Related

scanf keeps running nonstop

I have been trying to run the scanf() on my mac, but it never worked (took forever to run the program). Everything else like the printf works fine!
#include <stdio.h>
#include <stdlib.h>
int main(){
char name[20];
printf("What is your name? \n");
scanf("%19s", name);
return 0;
}
terminal
[Running] cd "/Users/yiminghuang/Documents/C/" && gcc scanf4.c -o scanf4 && "/Users/yiminghuang/Documents/C/"scanf4
[Done] exited with code=null in 8.611 seconds
[Running] cd "/Users/yiminghuang/Documents/C/" && gcc scanf4.c -o scanf4 && "/Users/yiminghuang/Documents/C/"scanf4
[Done] exited with code=null in 10.384 seconds
[Running] cd "/Users/yiminghuang/Documents/C/" && gcc scanf3.c -o scanf3 && "/Users/yiminghuang/Documents/C/"scanf3
[Done] exited with code=null in 15.999 seconds
I am new to C programming, so please excuse me if I fail to answer your question correctly!
Now, the program you wrote works perfectly fine but as soon as you enter a string separated by a space, it only takes the characters before the space.
To solve this problem, you can use fgets() function of C.
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int main(){
char name[MAX];
printf("What is your name? \n");
fgets(name, MAX, stdin);
printf("String = %s", name);
return 0;
}
//i have used fgets() here for getting the input
//it is a better option than gets()
//since it bounds your array and prevents buffer overflow
I have also added a printf() to check if the string is stored correctly.
IMPORTANT: fgets() also consider the newline character i.e. '\n' as a part of your string. So better to keep that in mind.
Check this question to know more about fgets()
Regards!

Certain C code not displaying output in VS Code

So basically, I have this simple Hello World program and when executed, it outputs correctly.
#include <stdio.h>
int main(){
printf("Hello");
}
Output: Hello
But for some reason adding a scanf command will cause the program to not output anything. It will display that it's running but it won't display anything.
#include <stdio.h>
int num1;
int main(){
printf("Enter number: \n");
scanf("%d", &num1);
printf("%d", num1);
}
Output:
[Running] cd "d:\programming\" && gcc main.c -o main && "d:\programming\"main
I know my code is okay since I tried it on other IDEs and it worked correctly. I even copied code from the internet and tried to run in VSCode but it still didn't work. It still works perfectly fine yesterday but this problem just pops in nowhere.
I use Visual Studio Code 1.62.3 with C/C++, C/C++ Compile Run, and Code Runner extensions.
It's a buffering problem. When standard output (stdout, where printf writes) is connected to an actual terminal then it's line-buffered, which means output is actually written to the terminal when there's a newline.
However, VSCode probably uses its own terminal emulation and uses pipes to connect stdout to that terminal. That means the output will be fully buffered, and you need to explicitly flush it.
So modify the code as such:
printf("Enter number: \n");
fflush(stdout); // Actually write the output to standard output
scanf("%d", &num1);
printf("%d", num1);
That it works for the first example is because then the process terminates, and all output is flushed automatically.

scanf() function failure

I installed the MingW C compiler and I am trying to compile and run a C program there.
I use Visual Stdio Code IDE.
OS is WINDOWS 10.
Compiler is MinGW.
My programs that do not use scanf() or gets() all run successfully but when I use scanf() function the program does not take input. I also used gets() function but that has the same problem. So when I press "run" button it does not give any output.
Here is my minimal reproducible example. Is this a compiler problem or is my code wrong?
#include <stdio.h>
int main()
{
int n;
printf("Enter a number: ");
//scanf("%d", &n);
}
OUTPUT for the above code is:
[Running] cd "d:\code\C\" && gcc #13sum.c -o #13sum && "d:\code\C\"#13sum
Enter a number:
[Done] exited with code=0 in 0.29 seconds
If I add a scanf():
#include <stdio.h>
int main()
{
int n;
printf("Enter a number: ");
scanf("%d", &n);
}
OUTPUT for the above code is:
[Running] cd "d:\code\C\" && gcc #13sum.c -o #13sum && "d:\code\C\"#13sum
[Done] exited with code=1 in 31.526 seconds
After using fflush(stdout);
#include <stdio.h>
int main()
{
int n;
printf("Enter a number: ");
fflush(stdout);
scanf("%d", &n);
}
[Running] cd "d:\code\C\" && gcc #13sum.c -o #13sum && "d:\code\C\"#13sum
Enter a number:
[Done] exited with code=1 in 2.804 seconds
After using fflush(stdout); printf() statement is executed but now I am unable to enter the value. I am typing but it is not showing in the output .
Compiler is not any giving errors in any of the above case.
the problem is your compiler its working fine for me.
your code take input until you enter 0 and then print the sum.
here's my output:-
Enter a number: 45 Enter a number: 34 Enter a number: 0 Sum is = 79%
so, check if you installed your mingw C compiler properly here.

How can you read numbers from keyboard until CTRL+D is pressed?

As the title says, I need to read numbers until CTRL+D is pressed. I was thinking about getchar() but i need to separate negative numbers from positive ones and i think it will be quite complicated like that.
you can use scanf to try to read a number (here I suppose int), and getchar (or equivalent) to both bypass non valid characters for a number and to detect EOF :
#include <stdio.h>
int main()
{
for (;;) {
int v;
if (scanf("%d", &v) == 1)
printf("read %d\n", v);
else
// bypass invalid char
if (getchar() == EOF)
break;
}
puts("done");
}
Compilation end executions :
pi#raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra c.c
pi#raspberrypi:/tmp $ ./a.out
12 aze -23
read 12
read -23
3 e
read 3
done
pi#raspberrypi:/tmp $
Under raspberrypi I enter two consecutive control-d to indicate EOF
Using echo to also produce the EOF :
pi#raspberrypi:/tmp $ echo "123 aze -23 " | ./a.out
read 123
read -23
done
pi#raspberrypi:/tmp $
When there is an invalid character I chosen to read only one character, it is also possible to bypass the rest of the line, or stop to read numbers, it is a choice.

How do I get GCC to work?

I am using Vim as my editor and GCC as my compiler, but it’s not working quite right. Let‘s say I am making a basic program to determine if a number is odd or even. Here is my code:
#include <stdio.h>
int main(int argc, char argv[])
{
int i;
printf("Enter a number: ");
scanf("%d\n", &i);
printf("%d\n", i);
if(i % 2 == 0)
{
printf("Your number is even.\n");
}
else if(i % 2 != 0)
{
printf("Your number is odd.\n");
}
else
{
printf("Invalid input.\n");
}
getchar();
return 0;
}
I'm not sure if I am programming this wrong, or gcc is just not a good compiler, or whatever. I am running linux, which I dual boot with windows. Now I press ctrl-d to stop the process, and only then does it print me back my number, and tell if it is odd or even. It isn't just this one, a lot of other programs with similar formats seem to do this to.
~ $ ./test
Enter a number: 45
45 //I press enter, nothing happends. Ctrl-d
Your number is even. //ctrl-d again
~ $
So what I'm asking is, is there a way to program it so that I don't have to quit the program in order for it to work, or is there another compiler that wouldn't have this problem? I am running on Ubuntu 14.04 dual booted with Windows 8.1.
\n in the format for scanf means "read until hit into non-whitespace character and then ignore them". Remove it and make the format for reading "%d".
to get gcc to work from vim,
goto the vim command prompt
shell gcc <and all needed parameters>
Or open another command window
set it to the same directory as the program being edited
gcc <and all needed parameters>
in general, try to make the compile step separate from the link step. I.E. to compile:
gcc -c <mySource.c> -Wall -Wextra -pedantic -std=c99 -o mySource.o
if any header files, other than those in the default 'include' path then add
-I<pathToHeaderFile>
which is often in the same directory so would be:
-I.
then link with:
gcc mySource.o -o mySource
You can add the -ggdb parameter to both lines if you plan on doing any debugging.
to add any library directories then on the link step append
-L<pathToLibrary>
to add any libraries then on the link step append, after any library parameters:
-l<shortLibName>
The initialization file for vim can contain the necessary info to invoke gcc by some keystroke combination, but I'm not totally familiar with the details.

Resources