简体   繁体   中英

How to print the char, integer, float and double values without using format specifiers in c

I want to print the char, int, float and double values without using format specifiers in my c program. I can able to print the string using the below code:

char s[] = "Hello\n";
fprintf(stdout, s);

how can I print the other data type values?

To print a char , use:

fputc(c, stream)

(If the stream is stdout , you can use putchar(c) .)

To print an int :

  • If the int is negative, print “-”.
  • Calculate the individual digits of the integer. This can be done either by calculating the digits from least significant to most significant and saving them in a buffer to be printed in reverse order or by figuring out where the most significant digit is and then calculating the digits from most significant to least significant. You can use a remainder operation, such as x % 10 , to calculate the least significant digit of a number, and you can use division, such as x / 10 , to remove that digit.
  • One caveat is that, if the original number is negative, you have to be careful about calculating its digits. The % operator will return negative values. Some people attempt to deal with this by negating the integer if it is negative. However, if the number is the least possible int , this may overflow. Eg, in many C implementations, the least int value is -2,147,483,648, but it cannot be negated because the greatest int is 2,147,483,647.
  • Any digit in numeric form (0 to 10) can be converted to a character (“0” to “9”) by adding '0' , such as int d = x % 10; char c = d + '0'; int d = x % 10; char c = d + '0'; . The C standard guarantees that this produces the appropriate character in c .
  • After you obtain the characters from the digits, print them.

To print a float or double :

  • Doing this completely correctly is hard, although it is a solved problem. The classic reference for it is Correctly Rounded Binary-Decimal and Decimal-Binary Conversions by David M. Gay .
  • If you just want a simple implementation suitable for a learning exercise, then you can format a floating-point value much as you would an integer: Calculate the digits individually. You also need to decide whether to print a fixed-point notation or a scientific notation (or other).
  • To print a fixed-point notation, print the integer part of the value as above, for integer types. Then print a “.” and some digits for the fractional part of the value.
  • To print a scientific notation, calculate the value of the exponent part (eg, to express 12345789 as “1.23456789e7”, the exponent is 7, for 10 7 . Divide the value by 10 raised to the power of that exponent and print the resulting value as a fixed-point number (so, in this example, you print “1.23456789”), then print “e”, the print the exponent part.
  • Floating-point rounding errors will occur in the above, making it suitable only for a learning exercise, not for use in a quality product.

The above should suffice to get you started. It is not complete code, obviously.

just one thought, not very optimal:

int myvalue = 12345;
char buffer[100];
size_t index = 0;

while (myvalue) {
  buffer[index] = '0' + myvalue % 10;
  myvalue = myvalue / 10;
  index++;
}
buffer[index] = '\0';

reverse(buffer);
fprintf(stdout, buffer);

you have to consider the negative sign. And the sizeof buffer (100 is a very bad guess).

To print a char as a character use fputc() .


To print an integer (including char ) in its decimal form, call either print_unsigned() or print_signed() , depending on if it is a signed integer or an unsigned integer.

The below uses recursion to print the most significant digits first.

For signed integers, it flips positive numbers to negative avoiding the undefined behavior of -INT_MIN .

int print_unsigned(uintmax_t x) {
  if (x >= 10) {
    if (print_unsigned(x / 10) == EOF) return EOF;
  }
  return fputc('0' + x % 10, stdout);
}

static int print_signed_helper(intmax_t x) {
  if (x <= -10) {
    if (print_signed_helper(x / 10) == EOF) return EOF;
  }
  return fputc('0' - x % 10, stdout);
}

int print_signed(intmax_t x) {
  if (x < 0) {
    if (fputc('-', stdout) == EOF) return EOF;
  } else {
    x = -x; // overflow not possible
  }
  return print_signed_helper(x);
}

The above stops early if the output causes an output error. EOF is something rarely returned from fputc() .


To printf a float of double : TBD code.

The short answer is that while it may be possible to hack something together that will do something RESEMBLING what you want (along the lines of Peter Miehle's solution posted in another answer), fundamentally C is not designed for this kind of functionality, and there is no support for it in the language. What you want is function overloading, which C++ and many other higher-level languages provide.

Even Peter Miehle's solution cannot be implemented as a function (in C), because what kind of argument would the function take? Either it is passed a type, in which case we KNOW the type and may as well use printf , or it is passed eg a void pointer, in which case, how can it implement the arithmetic operators without knowing the underlying data type the pointer points to?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM