1

For starters, I'm new to programming

I'd like to know how to store a number with leading zeroes in it with scanf instead of modifying the printf. Is it related to data types? If so, what is it? and how do I use it? I currently only know int, double and float

For example, I'd like to input the number "02" and receive "02" as the output, and when I input "2" the output will also be "2".

Val K
  • 11
  • 1
  • 2
  • 3
    There's no such number "02". You can store the string as is, or store the number of leading zeroes in the string (if any) separately. – Matt Sep 19 '18 at 17:12
  • you can store using C-string type: https://stackoverflow.com/a/7709467/2447581 – phibao37 Sep 19 '18 at 17:14
  • 1
    numeric types don't have a concept of leading zeros. They don't really even have the concept of the decimal number system. It's all just binary. – Christian Gibbons Sep 19 '18 at 17:14
  • Numbers don't have leading zeros. There is no such number as `01` or `099`. Those are string representations. – Ken White Sep 19 '18 at 17:15
  • 1
    Since you are new in programming - just to let you know that in C, strings are arrays of `char` (`char c[5];` is a 5 letter string) – Leonardo Alves Machado Sep 19 '18 at 17:21
  • 2
    Danger. A smart input routine would be forgiven for interpreting 010 as 8, since the leading 0 is used to designate an __octal__ constant. – Tim Randall Sep 19 '18 at 17:23
  • 3
    @LeonardoAlvesMachado Technically `char c[5]` would be a _4_ letter string, because the fifth char would be the terminating NUL byte, which is generally not considered a "letter" (e.g., as per `strlen`). Also a string in C is specifically an array of `char` terminated by a NUL byte, whereas a `char c[5]` may also just contain five `char`s that are not a string or used as one. – Arkku Sep 19 '18 at 17:35
  • 2
    @LeonardoAlvesMachado: `char c[5];` defines an array capable of holding 5 elements (of type `char`). A "string" needs a terminating `'\0'` byte, which must be in the underlying array. So, that `c` can hold strings up to a maximum of 4 letter length. – pmg Sep 19 '18 at 17:36
  • pmg and @Arkku are correct. I oversimplified it. – Leonardo Alves Machado Sep 19 '18 at 17:38
  • Also note that if you save the number as a string to preserve the original format but also do something with it internally after converting the string to a numerical type, you may end up hiding bugs, such as if the user types `010` and your output confirms that it is `010`, but internally it got interpreted as octal and the calculations were done with the number eight instead of the ten expected by the user. – Arkku Sep 19 '18 at 17:46

5 Answers5

4

The result of using scanf specifiers d, i, o, u, x, a, e, f, g is a mathematical number. There are no leading zeros. Conceptually, there are no digits in a number; it is a pure mathematical entity. (As Jonathan Leffler notes, leading zeros in the input matter the i specifier; a leading zero changes the base to octal while interpreting the numeral. This is for input only; the result is still a number with no associated digits or base.)

To preserve the leading zeros of a numeral, you must treat it as a string. scanf can be used to read strings or individual characters with the s, c, and [ specifiers, although you might wish to use a simple get-character function such as getchar. You would have to count the leading zeros yourself. The remaining digits could also be handled as a string, or you could convert them to a number.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • 1
    With `%i`, leading zeros matter — 017 and 17 are different values (octal 017 is 15 decimal; 17 is still 17 decimal). This catches people writing date parsing code using `%i` to scan for the day or the month (with `%i`, an input `09` gives a zero value, and leaves the 9 to be interpreted by the next conversion specifier). – Jonathan Leffler Sep 19 '18 at 17:58
4

how to store a number with leading zeroes (?)
I currently only know int, double and float

To store an integer and the leading zero count is then 2 pieces of information. When reading user input, record the number and its length or textual width.

" " to consume whitespace.
"%n" to record the offset of characters scanned so far. This does not affect the return value of scanf().

int num;
int n1, n2;
if (scanf(" %n%d%n", &n1, &num, &n2) != 1) {
  puts("Failed to read an int");
}

Otherwise, print it.
"0": pad with zeros.
"*": minimum width to print derived from argument list.

else {
  int length = n2 - n1;
  printf("%0*d\n", length, num);
}

Input/output

  007
007
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

If you store the number as an integer (e.g., int) or floating point type, any formatting information is inevitably lost: only the binary representation of the number is stored. (It may help to consider it as saving the idea of the number, e.g., "two", not how it looks when written.)

You need to store any additional information elsewhere, such as by saving the original string and using that for output, or by saving the number of digits and applying that to the printf format. There are also decimal number libraries that can internally save the decimal representation of the number, but that is considerably heavier than using the native types.

(Alternatively, just settle on a canonical output format and use that regardless of input. Is the goal really to preserve any input formatting as is, or would it suffice to always add the leading zeroes to the output?)

Arkku
  • 41,011
  • 10
  • 62
  • 84
1

As already explained, numbers don't have leading zeros.

You can however treat it as a string

printf("Enter num: ");
char buf[50];
scanf("%s", &buf);
printf("You entered: %s", buf);
Andreas DM
  • 10,685
  • 6
  • 35
  • 62
0

If you've got an int value, internally it's always represented as a certain number of bits (or whatever your CPU uses to store numbers) so you have no control over this.

There's always "leading zeroes" in terms of the internal format, because, for example, because 2099 is actually 0b00000000000000000000100000110011 in 32-bit form. This gets more complicated due to endian issues, but the principle still holds.

The only time leading zeroes makes sense is if you're using binary coded decimal, which has fallen out of style, or string notation such as produced by sprintf type functions.

It's only humans that care about digits. As far as a computer's concerned it's equally difficult to add 1+1 as it is 6916863870493370158+6471945999301299985 because they're both 64-bit operations.

tadman
  • 208,517
  • 23
  • 234
  • 262