I'm programming with gcc in CentOS 5.5 and the most of time I use printf() and fprintf() to print on terminal, but in some websites I've seen that some people use write(). I want to know if there's other ways to print on terminal.
Thanks.
There are some major differences between these functions.
The standard library provides some functions to output to stdout: printf, puts, putchar etc.
And some functions to output to a stream, you can specify the stream to stdout: fprintf, fputs, fwrite, etc.
But write is different, it's a low-level I/O function. The
standard library doesn't provide any low-level I/O functions. For
example, POSIX provides write that can output to a file
descriptor.
Google for how to use each one of them.
You could use puts() or putchar().
puts("Hello, world!\n");
There's a also fputs(), putc(), and fputc() if you want/need to specify a FILE* to write to.
All the output functions in the C standard I/O library could be used:
fprintf()
fputc()
fputs()
fputwc()
fputws()
fwprintf()
fwrite()
printf()
putc()
putchar()
puts()
putwc()
putwchar()
vfprintf()
vfwprintf()
vprintf()
vwprintf()
wprintf()
Most of the other write-like functions in POSIX could be used (but a few are reserved for sockets and those probably can't be used).
aio_write()
dprintf()
putc_unlocked()
putchar_unlocked()
pwrite()
vdprintf()
write()
writev()
There are many functions in the curses library that could be used.
Related
I have no issues with the library functions. I know that they work well. I am interested in their implementation. My question is: Can I write working versions of these functions for Windows x64 using only C?
Many of the stnadard library functions are written in C, and fopen, fread etc. are no exception. You can write a wrapper around open, read, write etc. which are usually lower level functions.
If those are not available, you can also do the same, calling the respective OS functions and wrapping them with your own implementation, you just have to make sure that they are complying to the standard.
Just as an example you can find a source for fopen here.
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.)
Why is there no dscanf function for reading from file descriptors?
We have fprintf, sprintf and dprintf for printing but for scanning there is only fscanf and sscanf.
It is not possible to write dscanf.
The scanf family requires that the stream is buffered, or else that it is capable of putting back a character that was read. POSIX file descriptors are neither.
Consider this stream
1234xyz
How would you scan a number off it? You cannot read it byte by byte and stop just before x. That would require clairvoyance. You also cannot read x and decide you don't need it, because you cannot put it back.
Because the printf and scanf family of functions is part of the C language, the functions handling file descriptors are not. Instead they are part of the operating system API (on POSIX platforms like Linux or OSX, other platforms emulate these system calls).
And the dprintf function is not a standard C function, it's an extension. From this printf (and family) manual page:
The dprintf() and vdprintf() functions were originally GNU extensions that were later standardized in POSIX.1-2008.
That there's no dscanf function is probably just an oversight from those who made the original dprintf extension.
I'm trying to migrate project written using unbuffered I/O ( open(), read(), write() functions) to buffered I/O ( fopen(), fread(), fwrite() functions).
I came across some dummy problem: Adapting zoo of open() flags to fopen() set r,r+,w,w+,a,a+.
It seems to be boring and error-prone. Is there some other way to do this?
I would use grep | sort | uniq to find all the cases in the source
code, then work out their translations, and write a simple Python script
to replace.
You can write some C macros with parameters (called open(), close() etc.) that expand to the right call. However, it is error prone as well. Therefore, I'd rather rely on some powerful editor (e.g., vim) and regular expressions for changing all occurences.
Actually other than the core C language, there is a C library. And if my understanding is right, functions like printf are part of C library. Now I have programmed in C in Turbo C in Windows as well as using gcc in Linux.
My question is: Are the code implementations of functions like printf the same in both Windows and Linux? Ultimately the printf function has to call a function in core OS (in both cases) that would display ASCII characters onto the screen? So since both the OS are different, will the implementation of code for printf be also different in both the cases?
Of course the implementation (of printf and all functions in <stdio.h>) is different (on Linux and on Windows), but the behavior should be conforming to the specification in the C11 or C99 standard.
Notice that printf does not show characters on the screen, but send them to the standard output (see printf(3)). Something else -e.g. the kernel tty layer and your terminal emulator on Linux- is displaying the characters on your screen (or elsewhere!).
On Linux and POSIX systems, <stdio.h> is ultimately using system calls to write data to a file descriptor. It would be write(2) (for printf) and the list of system calls is available in syscalls(2). Be aware that stdout is usually buffered (notably for performance reasons; making a write syscall for every written byte would be too costly). See fflush(3) & setvbuf(3). Try using strace(1) on your Linux program to understand the actually used syscalls.
On Windows, there is some equivalent thing (except that the list of syscalls on Windows is less documented and is very different).
BTW, GNU/Linux is mostly free software. So read Advanced Linux Programming then study the source code: the libc is often glibc (but could be musl-libc, etc... so you can have several implementations of printf on Linux, but usually you have one libc.so, even if you could have several ones), the kernel source is available on kernel.org.