Just starting out and working through cs50. I want to:
- prompt the user to input a number
- count the number of digits in that number
- if the number of digits is NOT equal to 13, 15, or 16: print "INVALID"
- if "INVALID" repeat from step 1
#include <cs50.h>
#include <stdio.h>
int main(void)
{
long n = 0;
n = get_long("Number: ");
int i = 0;
long cn = n;
while (cn > 0)
{
cn = cn / 10;
i ;
}
if (i != 13 && i != 15 && i != 16)
{
printf("INVALID\n");
}
}
This gets me through steps 1-3, but I cannot figure out how to get step 4 to work. Any help is greatly appreciated.
CodePudding user response:
Even simpler, loop continaully and use the snprintf (NULL, 0, ...)
trick to determine the number of digits. Break only if the number of digits is correct.
From man 3 snprintf
The functions
snprintf()
andvsnprintf()
do not write more than size bytes (including the terminating null byte ('\0'
)). If the output was truncated due to this limit, then the return value is the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available.
#include <cs50.h>
#include <stdio.h>
int main(void) {
long n = 0;
for (;;) { /* loop continually */
int ndigits = 0;
n = get_long("Number: ");
ndigits = snprintf (NULL, 0, "%ld", n);
if (n < 0) { /* subtract 1 for '-' sign */
ndigits -= 1;
}
if (ndigits == 13 || ndigits == 15 || ndigits == 16) {
break; /* break loop only if ndigits correct */
}
puts ("INVALID");
}
}
(note: technically '-'
isn't a digit, so you need to account for negative values)
Example Use/Output
./bin/ndigitstest
Number: 1
INVALID
Number: 123456789012
INVALID
Number: 1234567890123
Or, with negative values,
$ ./bin/ndigitstest
Number: -123456789012
INVALID
Number: -1234567890123
and so on...
CodePudding user response:
One has to be careful about making assumptions. The leading digit(s) may be 0, and the number value may not reflect what was entered.
#include <stdio.h>
#include <ctype.h> // for library function 'isdigit()'
#include "my_cs50.h" // my own library with its quirks
int main() {
for( ;; ) { // infinite loop to avoid tedium
char *ps = get_string( "Enter a number: " );
int cnt = 0;
while( isdigit( *ps ) ) {
ps ;
cnt ;
}
// my version of get_string() returns the trailing '\n'
if( ( *ps == '\0' || *ps == '\n' )
&& ( cnt == 13 || cnt == 15 || cnt == 16 ) )
; // all good
else
printf( "INVALID\n" );
}
return 0;
}
Output:
Enter a number: 1234567890123
Enter a number: 123456789012345
Enter a number: 1234567890123456
Enter a number: 12345678901234567
INVALID
Enter a number: 0000000000000
Enter a number: 0001112223334
Enter a number:
EDIT: Alternative version indicating how to continue processing with valid string of digits (and possible trailing '\n').
#include <stdio.h>
#include <ctype.h> // for library function 'isdigit()'
#include "my_cs50.h" // my own library with its quirks
int check_format( char *ps ) { // return 0 for bad, 1 for good
// THIS 'ps' is a local copy.
// Same value, but not the same variable as in main().
int cnt = 0;
while( isdigit( *ps ) ) {
ps ;
cnt ;
}
// my version of get_string() returns the trailing '\n'
return ( ( *ps == '\0' || *ps == '\n' )
&& ( cnt == 13 || cnt == 15 || cnt == 16 ) );
}
int main() {
for( ;; ) {// infinite loop to avoid tedium
char *ps = get_string( "Enter a number: " );
if( !check_format( ps ) ) {
printf( "INVALID\n" );
continue; // or something else???
}
/* perhaps more processing with validated string */
}
return 0;
}
CodePudding user response:
Simplest way is that you give a flag to check input is invalid or not. For example,
int invalid = 1;
long n = 0;
while (invalid) {
n = get_long("Number: ");
int i = 0;
long cn = n;
while (cn > 0)
{
cn = cn / 10;
i ;
}
if (i != 13 && i != 15 && i != 16)
{
printf("INVALID\n");
} else {
invalid = 0;
}
}