In my C program in an operating systems code (on the kernal side), I am trying to use kprintf to print a character, but when even I do, it prints it as well as some block character which has these four small circles in it.
kprintf(&ch);
Does anyone know whats going on here?
The printf() family of functions take a format string which tells what you want to print. You cannot print a character directly as you are doing, because printf() (or kprintf() as the case may be) will continue to read as if it were a string. You want something like:
kprintf("%c", ch);
The format string tells printf() what additional arguments to expect. In this case, %c indicates a character argument.
Related
Okay so, I'm pretty new to C.
I've been trying to figure out what exactly is the difference between putch() and putchar()?
I tried googling my answers but all I got was the same copy-pasted-like message that said:
putchar(): This function is used to print one character on the screen, and this may be any character from C character set (i.e it may be printable or non printable characters).
putch(): The putch() function is used to display all alphanumeric characters through the standard output device like monitor. this function display single character at a time.
As English isn't my first language I'm kinda lost. Are there non printable characters in C? If so, what are they? And why can't putch produce the same results?
I've tried googling the C character set and all of the alphanumeric characters there are, but as much as my testing went, there wasn't really anything that one function could print and the other couldn't.
Anyways, I'm kind of lost.
Could anyone help me out? thanks!
TLDR;
what can putchar() do that putch() can't? (or the opposite or something idk)
dunno, hoped there would be a visible difference between the two but can't seem to find it.
putchar() is a standard function, possibly implemented as a macro, defined in <stdio.h> to output a single byte to the standard output stream (stdout).
putch() is a non standard function available on some legacy systems, originally implemented on MS/DOS as a way to output characters to the screen directly, bypassing the standard streams buffering scheme. This function is mostly obsolete, don't use it.
Output via stdout to a terminal is line buffered by default on most systems, so as long as your output ends with a newline, it will appear on the screen without further delay. If you need output to be flushed in the absence of a newline, use fflush(stdout) to force the stream buffered contents to be written to the terminal.
putch replaces the newline character (\ n)
putchar is a function in the C programming language that writes a single character to the standard output
wprintf() takes a wchar_t string as argument and prints the string in the specified locale character encoding.
But I have noticed that when using printf() and passing it a UTF-8 string, the UTF-8 string will always be printed regardless of the specified locale character encoding (for example, if the UTF-8 string contains Arabic characters, and the locale is set to "C" (not "C.UTF-8"), then the Arabic characters will still be printed).
Am I correct that printf() doesn't care about the locale?
True printf doesn't care about locale for c-strings. If you pass it an UTF-8 string, it knows nothing about it, it just see a sequence of bytes (hopefully terminated by ascii NUL). Then, bytes are passed to the output as-is, and are interpreted by the terminal (or whatever is the output). If the terminal is able to interpret UTF-8 sequences it then does so (if not, it tries to interpret it the way it is configured, Latin-1 or alike) and if it is also able to print them correctly then it does so (sometimes it doesn't have the right font/glyph and prints unknown characters as ? or alike).
This is one of the big virtues (perhaps the biggest virtue) of UTF-8: it's just a string of reasonably ordinary bytes. If your code-editing environment knows how to let you type
printf("Cööl!\n");
and if your display environment (e.g. your terminal window) knows how to display it, you can just write that, and run it, and it works (as it sounds like you've discovered).
So you don't need special run-time support, you don't need special header files or libraries or anything, you don't need to write your code in some fancy new Unicodey way -- you can just keep on using ordinary C strings and printf and friends like you're used to, and it all just works.
Of course, those two if's can be big ones. If you can't figure out how to (or your code editing environment won't let you) type the characters, or if your display environment doesn't display them, you may be stuck, or you may have to do some hard work after all. (Display environments that don't properly display UTF-8 output from C programs are evidently quite common, based on the number of times the question gets asked here on SO.)
See also the "UTF-8 Everywhere" manifesto.
(Now, with all of this said, this doesn't mean that printf doesn't care about locale settings at all. There are aspects of the locale that printf may care about, and there may be character sets and encodings that printf might have to treat specially, in a locale-dependent way. But since printf doesn't have to do anything special to make UTF-8 work right, that one aspect of the locale -- although it's a biggie -- doesn't end up affecting printf at all.)
Let's consider the following simple program, which uses printf() to print a wide string if run without command-line arguments, and wprintf() otherwise:
#include <stdlib.h>
#include <locale.h>
#include <stdio.h>
#include <wchar.h>
const wchar_t hello1[] = L"تحية طيبة";
const wchar_t hello2[] = L"Tervehdys";
int main(int argc, char *argv[])
{
if (!setlocale(LC_ALL, ""))
fprintf(stderr, "Warning: Current locale is not supported by the C library.\n");
if (argc <= 1) {
printf("printf 1: %ls\n", hello1);
printf("printf 2: %ls\n", hello2);
} else {
wprintf(L"wprintf: %ls\n", hello1);
wprintf(L"wprintf: %ls\n", hello2);
}
return EXIT_SUCCESS;
}
Using the GNU C library and any UTF-8 locale:
$ ./example
printf 1: تحية طيبة
printf 2: Tervehdys
$ ./example wide
wprintf: تحية طيبة
wprintf: Tervehdys
i.e. both produce the exact same output. However, if we run the example in the C/POSIX locale (that only supports ASCII), we get
$ LANG=C LC_ALL=C ./example
printf 1: printf 2: Tervehdys
i.e., the first printf() stopped at the first non-ASCII character (and that's why the second printf() printed on the same line);
$ LANG=C LC_ALL=C ./example wide
wprintf: ???? ????
wprintf: Tervehdys
i.e. wprintf() replaces wide characters that cannot be represented in the charset used by the current locale with a ?.
So, if we consider the GNU C library (which exhibits this behaviour), then we must say yes, printf cares about the locale, although it actually mostly cares about the character set used by the locale, and not the locale per se:
printf() will stop when trying to print wide strings that cannot be represented by the current character set (as defined by the locale). wprintf() will output question marks for those characters instead.
libc6-2.23-0ubuntu10 on x86-64 (amd64) does some replacements for multibyte characters in the printf format string, but multibyte characters in strings printed with %s are printed as-is. Which means it is a bit complicated to say exactly what gets printed and when the printf() gives up on the first multibyte or wide character it cannot convert, or just prints as-is.
However, wprintf() is pretty rock solid. (It too may choke if you try to print narrow strings with multibyte characters not representable in the character set used by the current locale, but for wide string stuff, it seems to work very well.)
Do note that POSIX.1 C libraries also provide iconv_open(), iconv(), and iconv_close() for converting strings, as well as mbstowcs() and wcstombs() to convert between wide and narrow/multibyte strings. You can also use asprintf() to create a dynamically allocated narrow string out of narrow and/or wide character strings (%s and %ls, respectively).
I was learning from geeksforgeeks and when i saw this, a thought came in my mind that as getchar() and other similar functions returns an int(whether due to failure of program or EOF) then why format specifier used is %c, why not %d(or %i).
// Example for getchar() in C
#include <stdio.h>
int main()
{
printf("%c", getchar());
return 0;
}
I know that the character we input in is a character and it is taken by the function getchar() and we are displaying it using %c.
But my problem is what's actually happening inside getchar() and printf() during the whole process, where getchar() is returning that integer, where it is getting stored and how the character we inputted is getting displayed by printf() i.e.what's happening inside printf()?
I did some research on printf() implementation and get to know that printf is part of the C standard library (a.k.a. the libc) and is a variadic function(printf) but i didn't came to know that what is really happening inside this function and how it knows by format specifier that it has to print character or int?
Please help me learning the whole detailed process which is going on.
The man page for getchar says the following:
fgetc() reads the next character from stream and returns it as an
unsigned char cast to an int, or EOF on end of file or error.
getc() is equivalent to fgetc() except that it may be implemented as a
macro which evaluates stream more than once.
getchar() is equivalent to getc(stdin).
So let's say you enter the character A. Assuming your system uses ASCII representation of characters, this character has an ASCII value of 65. So in this case getchar returns 65 as an int.
This int value of 65 returned by getchar is then passed to printf as the second argument. The printf function first looks at the format string and sees the %c format specifier. The man page for printf says the following regarding %c:
If no l modifier is present, the int argument is converted to an
unsigned char, and the resulting character is written.
So printf reads the next argument as an int. Since we passed in a int with value 65, that's what it reads. That value is then cast to an unsigned char. Since it is still in the rage of that type, the value is still 65. printf then prints the character for that value. And since 65 is the ASCII value for the character A, the character A is what appears.
To understand you must read default argument promotions.
where getchar() is returning that integer, where it is getting stored
C handle this for you.
how the character we inputted is getting displayed by printf()
%c tell to printf() to print a character.
(I am supposing your computer has an x86-64 processor and runs Linux)
why format specifier used is %c, why not %d(or %i).
Imagine that the corresponding argument (to printf) was 99 (an int). If you use %c then the letter c (of ASCII code 99) is displayed. If you use %d or %i then 99 is displayed by printf, etc...
printf is, as you noticed, a variadic function. It is implemented using variadic primitives like va_start and va_end which are macros expanded to some builtin known to the compiler. How exactly arguments are passed and results are given (the calling convention) is defined (in some processor & OS specific way) in a document called ABI (application binary interface).
On some C standard library implementations, printf (and related functions, like vfprintf) would ultimately use putc or something related.
Notice that standard I/O functions (those in <stdio.h>) are likely to be provided with the help of some operating system. Read Operating Systems : Three Easy Pieces for more about OSes.
Quite often, the C standard library will use some system calls to interact with the operating system kernel. For Linux these are listed in syscalls(2), but read Advanced Linux Programming. To output some data the write(2) syscall would be used (but the C standard library is generally buffering, see setvbuf(3)).
BTW, for Linux/x86-64 both GNU glibc & musl-libc are free software implementations of the C standard library, and you can study their source code (most of it is coded in C, with a tiny bit of assembly for the system call glue).
But my problem is what's actually happening inside getchar() and printf() during the whole process, where getchar() is returning that integer, where it is getting stored ...?
The ABI defines that the result of an int returning function goes thru register %rax, and getchar (like every other int return function) works that way. See the X86-64 Linux ABI referenced here.
... and how the character we inputted is getting displayed by printf() i.e. what's happening inside printf()?
After many software layers, when the stdout stream gets flushed (e.g. by some call to fflush(3), by a \n newline character, or at exit(3) time, including returning from main into crt0 code), the C standard library will use the write(2) syscall. The kernel will process it to show something (But details are horribly complex, read first the tty demystified). Actually millions of source code lines are involved (including inside the kernel - read about DRM, inside the display server such as X.Org or Wayland - also some code inside the GPU -, inside the terminal emulator). Linux is free software, so in principle you can study all of it (but that needs more than a lifetime, a typical Linux distribution has about twenty billions lines of source code). See also OSDev wiki which gives some practical information, including about native Intel grapĥics (which are the most primitive graphics today).
PS. You need to spend more than ten years understanding all the details (and I don't).
please take a look at the two following c statements
printf("a very long string");
printf("%s","a very long string");
they produce the same result,but there is definitely some difference under the hood,so what is the difference and which one is better? Please share your ideas!
If you know what the string contents are, you should use the first form because it is more compact. If the string you want to print can come from the user or from any other source such that you do not know what the string contents are, you must use the second form; otherwise, your code will be wide open to format string injection attacks.
The first printf works like this
'a' is not a special character: print it
' ' is not a special character: print it
'v' is not a special character: print it
...
'g' is not a special character: print it
The second printf works like this
'%' is a special character:
's' print the contents of the string pointed to by the 2nd parameter
The first one passes one parameter and the second passes 2, so the call is slightly faster in the first one.
But in the first one, printf() has to scan the long string for format specifications and in the second one, the format string is very short, so the actual processing is probably faster in the second one.
More important (to me anyway), is that "a very long string" is not likely to be a a constant string as it is in this example. If you're printf'ing a long string, you're probably using a pointer to to something that the program generated. In that case, it's a MUCH better idea to use the second form because otherwise somewhere, somehow, sometime, the long string will contain a format printf format specification and that will cause printf to go looking for another argument and your program will crash. This exact problem just happened to me about a week ago in code that we have been using for nearly 20 years.
The bottom line is that your printf format specification should always be a constant string. If you need to output a variable, use printf("%s",var) or better yet, fputs(var, stdout).
The first is no less efficient than the second. Since there are no format sequences and no corresponding arguments, no work must be done by the printf() function. In the second case, if the compiler isn't smart enough to catch this, you will be calling for unnecessary work (note: miniscule compared to actually sending (and reading!) the output at the terminal.
printf was designed for printing with formatting. It is more useful to provide formatting arguments for the sake of debugging although they aren't required.
%s takes a value of a const char* whereas leaving no argument just prints the literal expression.
You could still cast a different pointer to the const char* explicitly and change its contents without changing the output expression.
First of all you should define "better" better since it is not smart enough by itself. Better in what way? performance, maintenance, readibility, extensibilty ...
With the one line of code presented I would choose option 1 for almost all versions of 'better'
It's more readible
It does what it should do and nothing more (KISS principle)
It's faster (no pointless moving memory around to stuff one string into another). But unless you are doing this printf a hell of a lot of times in a loop this is not that a big plus.
printf("/*something else*/"); /*note that:without using \n in printf*/
I know printf() uses a buffer which prints whatever it contains when, in the line buffer, "\n" is seen by the buffer function. So when we forget to use "\n" in printf(), rarely, line buffer will not be emptied. Therefore, printf() wont do its job. Am I wrong?
The example you gave above is safe as there are no variable arguments to printf. However it is possible to specify a format string and supply variables that do not match up with the format, which can deliver unexpected (and unsafe) results. Some compilers are taking a more proactive approach with printf use case analysis, but even then one should be very, very careful when printf is used.
From my man page:
These functions return the number of characters printed (not including
the trailing \0 used to end output to strings) or a negative value
if an output error occurs, except for snprintf() and vsnprintf(), which
return the number of characters that would have been printed if the n
were unlimited (again, not including the final \0).
So, it sounds like the can fail with a negative error.
Yes, output to stdout in C (using printf) is normally line buffered. This means that printf() will collect output until either:
the buffer is full, or
the output contains a \n newline
If you want to force the output of the buffer, call fflush(stdout). This will work even if you have printed something without a newline.
Also printf and friends can fail.
Common implementations of C call malloc() in the printf family of the stdC library.
malloc can fail, so then will printf. In UNIX the write() call can be interrupted by EINTR, so context switching in UNIX will trigger faults (EINTR). Windows can and will do similar things.
And... Although you do not see it posted here often you should always check the return code from any system or library function that returns a value.
Like that, no. It won't always work as you expect, especially if you're using user input as the format string. If the first argument has %s or %d or other format specifiers in it, they will be parsed and replaced with values from the stack, which can easily break if it's expecting a pointer and gets an int instead.
This way tends to be a lot safer:
printf("%s", "....");
The output buffer will be flushed before exit, or before you get input, so the data will make it regardless of whether you send a \n.
printf could fail for any number of reasons. If you're deep in recursion, calling printf may blow your stack. The C and C++ standards have little to say on threading issues and calling printf while printf is executing in another thread may fail. It could fail because stdout is attached to a file and you just filled your filesystem, in which case the return value tells you there was a problem. If you call printf with a string that isn't zero terminated then bad things could happen. And printf can apparently fail if you're using buffered I/O and your buffer hasn't been flushed yet.