Experts I've doubts in gets(),puts() and getch().
Why do we use gets() and puts() when we have scanf() and printf()?
What is the use of getch().
Please explain this in simple language because I'm a beginner.
THank you in advance. :)
gets doesn't exist anymore (except in outdated environnments such as the infamous TurboC), use fgets instead.
fgets reads one line of text from a file including from the terminal (standard output)
puts writes one line of text to the terminal (standard output)
fputs writes one line of text to a file, including the terminal (standard output)
getch reads on character from the standard input (terminal)
printf and friends allow you to print formatted output
scanf and friends allow you to read formatted input.
Why do we use gets() and puts() when we have scanf() and printf()?
We don't use gets(), the function was so poorly designed that it was flagged obsolete 18 years ago and finally completely removed from the C language 6 years ago. If someone taught you to use gets(), you need to find a more updated source of learning. See What are the C functions from the standard library that must / should be avoided?.
puts(str) is only used as a micro-optimization of printf("%s", str). puts() is traditionally ever so slightly faster than printf(), since it doesn't need to parse a format string. Today, this performance benefit is a non-issue.
However, puts() is much safer than printf(). You can write bad code like printf("%s", pointer_to_int) and it might compile without warnings. But puts(pointer_to_int) will never compile without warnings/errors.
Generally, most of stdio.h is dangerous and unsafe because of the poor type safety. It is avoided in professional, production-quality code. For student/hobbyist purposes, printf/scanf are however fine.
What is the use of getch()
getch() was a non-standard extension to C, which allowed programs to read a character from stdin without echoing the typed character to stdout (the screen).
This function was popular back in the days of MS DOS when Borland Turbo C was the dominant compiler. Because Turbo C had it, some other compilers also started supporting it together with the non-standard conio.h library. We're talking early 1990s.
You shouldn't use this function in modern C programming.
(Though it is possible to implement it yourself with various API calls, as in this example for Windows.)
Related
Noob Q, best-practices related:
I'm writing a MS BASIC interpreter for macOS using yacc/lex/C. It uses scanf/printf for PRINT and INPUT. I would like to add a CLI option to redirect those to files.
I know how to do this technically, using fopen/fclose and fprintf etc.. But is that how "real" Unixen programs would do it? I would like to be as standard as possible to avoid confusion when someone else examines the code.
On generic Unix/Linux/FBSD, would you...
replace all the printf with fprintf(fp, and default fp to stdout?
keep all the printfs but redirect stdout?
rely on the shell and piping and not offer this as a CLI option at all?
(For a general program)
There's nothing wrong with simply relying on normal redirection by the parent (like the shell), but if your want to provide a parameter for that (which is also perfectly fine).
As for using printf or fprintf, I don't see much difference. I would probably choose one or other depending on the typical case. If it was almost always output on stdout, would probably use printf and fprintf otherwise. The part that may be confusing is that another person reading your code may not realize that printf isn't the program standard output (as for the redirection, you can use freopen or -before using stdio- dup2(, 1);).
(For your BASIC interpreter)
In this case, as you are translating INPUT and PRINT, scanf and printf seem the logical choices, and I'm not sure why you would need an option to change them to something else.
I found this the above type of code in a pre-completed portion of a coding question in Hackerrank. I was wondering what \n would do? Does it make any difference?
Read some good C reference website, and perhaps the C11 standard n1570 and probably Modern C.
The documentation of scanf(3) explains what is happening for \n in the format control string. It is handled like a space and matches a sequence of space characters (such as ' ', or '\t', or '\n') in the input stream.
If you explicitly want to parse lines, you would use some parser generator like GNU bison and/or use first fgets(3) or getline(3) and later sscanf(3).
Don't forget to handle error cases. See errno(3). Consider documenting using EBNF notation the valid inputs of your program.
Study for inspiration the source code of existing open source programs, including GNU bash or GNU make. Be aware than in 2020 UTF-8 should be used everywhere (then you might want to use libunistring whose source code you could study and improve, since it is free software).
If you use Linux, consider using gdb(1) or ltrace(1) to understand the behavior of your program. Of course, read the documentation of your C compiler (perhaps GCC) and debugger (perhaps GDB).
I'm trying to emulate a terminal using a C program in Linux and need my program to display a custom prompt while the program executes. Is there a way to display it using my C program? (I can always try to printf "My-prompt" every line manually, but I'm looking for a better way). Also I can't use any additional libraries other than the basic ones so GNU Readline library and editline library wouldn't work (as suggested in another thread).
for example:
user#mypc:~$ ./a.out
my_custom_prompt>3+5
my_custom_prompt>8
my_custom_prompt>exit
user#mypc:~$
I believe what the OP wants is to simply have the "prompt" printed along with any program output, without having to add this manually every time. There is a way to do this, if you write a wrapper function on top of printf to do this, and call that instead of printf directly.
Probably this will help: http://www.ozzu.com/cpp-tutorials/tutorial-writing-custom-printf-wrapper-function-t89166.html
In your example, you already have got a terminal. You want to write a command-line interface with a prompt, not a terminal.
I can always try to printf "My-prompt" every line manually, but I'm looking for a better way
There’s nothing wrong with this approach. You have a loop which prints the prompt and waits for input afterwards. As Kunerd said in the comment, one line of code.
Normally, a prompt is printed to stderr rather than stdout. This has the advantage, that the prompt appears before a newline is written, as stderr is unbuffered (and in combination with piping and redirection it seems reasonable to me, that this stuff doesn’t go to the same stream as the actual output).
Also I can't use any additional libraries other than the basic ones so GNU Readline library and Editline library wouldn't work
Doing this in a way strictly conforming to the C standard and not using any libraries but the standard one makes things like line editing (other than using backspace) or a command history (close to) impossible. If that’s OK for you, look for fgets etc. and keep in mind, that stdin is usually line-buffered.
POSIX specifies some additional properties of terminals, see e.g. http://pubs.opengroup.org/onlinepubs/9699919799/. Maybe curses is also of interest for you.
Perhaps you're looking for fgets() documentation?
Why C standards contain many unsafe functions, which are useless (in good programs them don't use) and harmful, for example getchar? Why C standard doesn't contain instead of them the useful functions, for example getch, and getche? It is only one of many examples...
UPD
I confused: gets instead of getchar.
Do you mean gets? To not break old programs. The road to obsoleteness is long.
And besides, it has been deprecated.
gets is deprecated in C99 and has been removed in C11.
C11(ISO/IEC 9899:201x) Forward/6
removed the gets function ()
You can't implement getch() [reading without buffering] on a teletype (terminal that looks like a typewriter). Or any type of terminal where the data is stored in the terminal until you hit enter.
There are functions that do this sort of things, but remember that C is a language that is supposed to "run on anything".
gets was part of the standard library many years ago, so it has to stay - otherwise, old code won't compile, and a lot of people like to use old code (because it's a lot of work to fix up 1000000 lines of messy code that used to work!)
How can I do cursor control with ANSI using escape sequences using Turbo C? Here I've provided a code, but it's not yet working in my TurboC.
main()
{
while( getche() != '.' )
printf("\x1B[B");
}
Apart from the possibility that that output may be line buffered (meaning nothing may appear until you send a newline), you should probably also ensure that ANSI.SYS is loaded, since it's the device driver responsible for interpreting those sequences.
But I'm wondering why you're doing this. From memory (admittedly pretty faded memory), Turbo C has calls for doing this sort of thing, gotoXY and clrscr and such.
A way of putting escape character with printf() is:
printf("%c[B", 0x1b);
But usually (I don't know Turbo C), there are libraries for doing terminal related stuff in a portable way.