In C, qual è il modo migliore per ignorare le virgole quando si utilizza scanf
su un numero come 1.000.000?In C, Come utilizzare scanf per scansionare in 1.000.000 ignorando le virgole
risposta
Esistono diversi modi per rimuovere le virgole (o qualsiasi altro carattere che si desidera saltare). Uno dei più facili (e più flessibili) è semplicemente camminare due puntatori lungo la stringa di input spostando tutte le cifre insieme ignorando le virgole. (devi essere sicuro di nul-terminate dopo l'ultima cifra).
Un esempio potrebbe essere:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#define MAXC 25
long xstrtol (char *p, char **ep, int base);
int main (void) {
char string[MAXC] = "";
char *rp, *wp; /* a read pointer and write pointer */
int c;
long n = 0;
rp = wp = string;
printf ("enter number with ',': ");
if (!fgets (string, MAXC, stdin)) {
fprintf (stderr, "error: insufficient input.\n");
return 1;
}
/* work down each char in string, shifting number together */
while (*rp && (('0' <= *rp && *rp <= '9') || *rp == ',')) {
if (*rp == ',') { rp++; continue; } /* skip commas */
*wp++ = *rp; /* shift digits together */
rp++;
}
*wp = 0; /* nul-terminate */
if (*rp != '\n') /* flush input buffer */
while ((c = getchar()) != '\n' && c != EOF) {}
printf ("\n string : %s\n", string);
n = xstrtol (string, &rp, 10); /* convert string to long */
printf(" n : %ld\n\n", n);
return 0;
}
/** a simple strtol implementation with error checking.
* any failed conversion will cause program exit. Adjust
* response to failed conversion as required.
*/
long xstrtol (char *p, char **ep, int base)
{
errno = 0;
long tmp = strtol (p, ep, base);
/* Check for various possible errors */
if ((errno == ERANGE && (tmp == LONG_MIN || tmp == LONG_MAX)) ||
(errno != 0 && tmp == 0)) {
perror ("strtol");
exit (EXIT_FAILURE);
}
if (*ep == p) {
fprintf (stderr, "No digits were found\n");
exit (EXIT_FAILURE);
}
return tmp;
}
(nota:xstrtol
fornisce semplicemente controllo di errori sulla conversione di string
a long
)
utilizzo/Output
$ ./bin/nwithcomma
enter number with ',': 1,234,567
string : 1234567
n : 1234567
Guardalo e fammi k ora se avete domande. Puoi controllare INT_MIN
e INT_MAX
se vuoi trasmettere il risultato a int
, ma è altrettanto semplice lasciare la risposta come long
.
Come una funzione
Come sottolineato, sarebbe molto più utile come una funzione. È possibile spostare il codice per una semplice funzione di conversione, e regolare il codice principale come segue:
...
#define MAXC 25
long fmtstrtol (char *s);
long xstrtol (char *p, char **ep, int base);
int main (void) {
char string[MAXC] = "";
printf ("enter number with ',': ");
if (!fgets (string, MAXC, stdin)) {
fprintf (stderr, "error: insufficient input.\n");
return 1;
}
printf(" number : %ld\n\n", fmtstrtol (string));
return 0;
}
/* convert comma formatted string to long */
long fmtstrtol (char *s)
{
if (!s || !*s) {
fprintf (stderr, "fmtstrtol() error: invalid string.\n");
exit (EXIT_FAILURE);
}
char *rp, *wp; /* read pointer, write pointer */
int c;
rp = wp = s;
while (*rp && (('0' <= *rp && *rp <= '9') || *rp == ',')) {
if (*rp == ',') { rp++; continue; }
*wp++ = *rp;
rp++;
}
*wp = 0;
if (*rp != '\n') /* flush input buffer */
while ((c = getchar()) != '\n' && c != EOF) {}
return xstrtol (s, &rp, 10);
}
...
Perché un programma di lavoro completo? Potrebbe essere una funzione. – haccks
È vero, era solo un esempio dall'alto in basso che non ho riformattato in una funzione ': (' –
@haccks - pigrizia corretta - funzione fornita ':)' –
Direi che il modo migliore è quello di non utilizzare scanf
per questo. Almeno non usare alcun formato numerico.
Leggere invece come stringa, quindi rimuovere le virgole e infine convert to a number.
Questa è una buona idea! Grazie, lo farò – Dizzzyp
mentre (scanf ("% 4 [^,],% 4 [^,],% 79 [^,] ,% d ", sem, type, title, & value) == 4) prova questo – Jois
Non lo so, ma forse il comando [locale] (http://www.gnu.org/software/libc/manual /html_node/Locales.html#Locales)? –