1

For a simple program, the assignment was to create a program that accepts a ten digit phone number, and then reads it back to the user. There were to be controls to ensure that:

  1. The first digit is not 0.

  2. That the number entered is ten numbers.

The error check seemed simple; I thought using a while loop to ensure that the range of the number was between 1000000000 and 9999999999 would work out, and according to independent calculations, it seems it should.

while ((MDN - valueCheck < 0) || (MDN > 9999999999)) {
  printf("Entered number is not ten digits. Please re-enter.\n");
  scanf("%d", &MDN);
}

Both MDN and valueCheck are long long type variables (so that the range can go past 2,147,483,647; IIRC long long was 64-bit), but they seem to still be listed as 32-bit integers, as entering 2147483647 comes out just fine (or any lower phone number works as well), but entering 2,147,483,648 (or anything above) causes it to be displayed as -2147483647.

Related to the above, entering a higher number, not only does the value wrap around the range of the 32-bit integer, but the phone number printed by the printf statement after the loop is always equal to the entered number minus twice the limit of a 32-bit integer.

Is there any simple way to make the program actually work in 64-bit numbers like I wanted it to? The algorithm seems solid, if I can make the math work properly.

alk
  • 69,737
  • 10
  • 105
  • 255
Chris B
  • 81
  • 2
  • 8

3 Answers3

5

Try scanf("%lld", &MDN); instead of scanf("%d", &MDN);

From man scanf:

ll (ell ell)
              Indicates that the conversion will be one of dioux or n and the
              next pointer is a pointer to a long long int (rather than int).
Charlie Burns
  • 6,994
  • 20
  • 29
1

Q: Is there any simple way to make the program actually work in 64-bit numbers like I wanted it to?
A: Use int64_t and "%" SCNx64.

If you:
want 32-bit integers, use type int32_t.
want 64-bit integers, use type int64_t.
use int, the range is at least -32767 to +32767.
use long, the range is at least -2147483647 to +2147483647.
use long long, the range is at least -9223372036854775807 to +9223372036854775807.

With scanf() use the matching format specifier:

int               "%d"  
long              "%ld"  
long long         "%lld"  
int32_t           "%" SCNx32  
int64_t           "%" SCNx64  
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

You could've used this:

scanf("%lld", &MDN);

but there are issues with coding and approach itself (see below)
I would advise to stick to string-regexp input-validation approach instead.

Coding issue:

scanf() in a loop is vulnerable to unprocessed-input-buffer issue, e.g if user enters a text instead of a number - scanf() will fail, stdin won't be consumed and loop will continue eternally.

See "How to clear input buffer in C?" for details. Following change should address it:

while(!scanf("%lld", &MDN)) {
    char c;
    while(c=getchar()!='\n'&& c!=EOF);
}

Approach issue:

The approach itself is vulnerable to overflow and type-trimming issues.
For example: "-9999999999999999999" will pass all MDN validations (see below).

Also there could be compiler/specific issues while comparing long long (MDN)
to an integer (0 or 9999999999 instead of 0LL or 9999999999LL).

Entered number is not ten digits. Please re-enter.
-9999999999999999999
"MDN" is -9223372036854775808
"MDN > 9999999999" is false
"MDN - valueCheck < 0" is false (!) because "MDN - valueCheck" is 9223372035854775808
Community
  • 1
  • 1
Vlad
  • 1,157
  • 8
  • 15