Εναλλακτική δηλαδή του...
- Μορφοποιημένος Κώδικας: Επιλογή όλων
-
scanf("%d", &n);
η οποία δεν θα υποφέρει από κανένα από τα συμπτώματα του παραπάνω (π.χ. line buffering, range overflow/underflow, κλπ).
Συντονιστής: konnn
scanf("%d", &n);

#include <stdio.h>
#define ABSOLUTE_VALUE(x) ((x) >= 0 ? (x) : (-(x)))
int number_digits(int x)
{
int i;
if (!x) return 0;
x = ABSOLUTE_VALUE(x);
for (i = 0; x; x /= 10, i++);
return i;
}
int main(void)
{
int i, y, digits;
for (i = 1; i <= 30000; i++) {
digits = number_digits(i-1);
for (y = 0; y < digits; y++)
putchar('\b');
printf("%d", i);
}
return 0;
}

#include <stdio.h>
#include <stdlib.h> /* strtol() */
#include <limits.h> /* INT_MIN, INT_MAX */
/*********************************************************//**
* @brief Read into existing cstring s up to (ssize-1) chars from stdin or until
* ENTER is pressed, and null terminate it (removing ENTER if necessary).
* If more than (len-1) chars have been typed before the ENTER is pressed,
* they are ignored and they are removed from the stdin buffer.
*
* @return A pointer to the start of read s, or NULL on error.
*************************************************************
*/
char *s_getsflushed( char *s, const size_t ssize )
{
const size_t charsize = sizeof(char);/* don't assume 1 byte == sizeof(char) */
size_t i = 0;
/* sanity checks */
if ( !s )
return NULL;
if ( ssize < charsize )
return s;
/* read chars from stdin */
for (i=0; (s[i]=getc(stdin)) != '\n' && i < ssize-charsize; i += charsize)
; /* ... empty loop-body */
if ( s[i] != '\n' ) { /* ssize reached without '\n' */
s[i] = '\0'; /* ... null terminate s */
while (getchar() != '\n') /* ... flush remaining chars */
; /* ... ... empty loop-body */
}
else
s[i] = '\0';
return s;
}
/*********************************************************//**
* @brief Read safely an integer form stdin.
* @return The integer, or INT_MIN if input contained non-digits (including blanks),
* or INT_MAX in case of out of range integer value.
*************************************************************
*/
int readInt( void )
{
char input[ 255+1 ] = {'\0'};
char *tail = NULL;
long int ret = INT_MAX; /* INT_MAX & INT_MIN denote errors (see comments above) */
/* input failure? */
if ( !s_getsflushed(input, 255+1) )
return INT_MAX;
ret = strtol(input, &tail, 10 );
/* blank or non-digit chars in input? */
if ( '\0' != *tail || (tail == input && 0 == ret) )
return INT_MIN;
/* over/underflowed input? */
if ( ret > INT_MAX-1 || ret < INT_MIN+1 )
return INT_MAX;
/* everything ok */
return (int)ret;
}
/* ------------------------------------------------- */
int main( void )
{
int n;
printf( "Enter a valid integer: " );
n = readInt();
if ( INT_MAX == n )
puts("*** error: out of range integer!");
else if ( INT_MIN == n )
puts("*** error: blank or non-digit chars in input!");
else
printf( "%d was a valid input\n", n );
system("pause"); /* windows only */
return 0;
}

Ilias95 έγραψε:Ορίστε:
- Μορφοποιημένος Κώδικας: Επιλογή όλων
#include <stdio.h>
#define ABSOLUTE_VALUE(x) ((x) >= 0 ? (x) : (-(x)))
int number_digits(int x)
{
int i;
if (!x) return 0;
x = ABSOLUTE_VALUE(x);
for (i = 0; x; x /= 10, i++);
return i;
}
int main(void)
{
int i, y, digits;
for (i = 1; i <= 30000; i++) {
digits = number_digits(i-1);
for (y = 0; y < digits; y++)
putchar('\b');
printf("%d", i);
}
return 0;
}
Την number_digits() την έγραψα αμέσως, ένα χαζό λάθος είχα στη λογική του loop που μου πήρε κάποια ώρα να το βρω.
Επίσης, νομίζω η number_digits() είναι re-usable.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define MAXINPUT (255+1)
/* console backspace ntimes */
#define NBS( ntimes ) \
do { \
int nTImeSTMp = (ntimes); \
while (nTImeSTMp--) \
putchar('\b'); \
} while(0)
/* ------------------------------------------------- */
int main( void )
{
char input[ MAXINPUT ] = {'\0'};
int uplim = 0;
short i = 0;
do {
printf( "Enter upper limit (1 - %hd): ", SHRT_MAX );
fgets( input, MAXINPUT, stdin);
uplim = atoi(input);
} while ( uplim < 1 || uplim > SHRT_MAX);
printf( "Counter: " );
for (i=0; i < uplim; i++)
NBS( printf("%hd", i) );
putchar('\n');
system("pause"); /* windows only */
return 0;
}

do { \
int nTImeSTMp = (ntimes); \
while (nTImeSTMp--) \
putchar('\b'); \
} while(0) int nTImeSTMp = (ntimes); \
while (nTImeSTMp--) \
putchar('\b'); \
short int n;
/* read n here */
if ( n > SHRT_MAX || n < SHRT_MIN ) ...

Ilias95 έγραψε:Απορία.
Γιατί;
...
Και όχι:
...
for (i=0; i < uplim; i++)
NBS( printf("%hd", i) );
for (i=0; i < uplim; i++)
int nTImeSTMp = (ntimes);
while (nTImeSTMp--)
putchar('\b');\
for (i=0; i < uplim; i++)
do {
int nTImeSTMp = (ntimes);
while (nTImeSTMp--)
putchar('\b');
} while( 0 );


Ilias95 έγραψε:Σωστά. Απλά δεν έχω δει ακόμα macro definitions.
Οπότε φαντάζομαι εκτός απ' αυτά που είναι μία γραμμή τα υπόλοιπα ορίζονται πάντα σε do-while.
