В C, как использовать scanf для сканирования в 1,000,000, игнорируя запятые
В C, каков наилучший способ игнорировать запятые при использовании scanf
на номер 1,000,000?
2 ответов
существует несколько способов удаления запятых (или любого другого символа, который вы хотите пропустить). Один из самых простых (и наиболее гибких) - просто пройти два указателя по входной строке, сдвинув все цифры вместе, игнорируя запятые. (вы должны быть уверены, что nul-terminate после последней цифрой).
пример:
#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;
}
(Примечание: xstrtol
просто обеспечивает проверку ошибок при преобразовании string
в long
)
Использовать/Выход
$ ./bin/nwithcomma
enter number with ',': 1,234,567
string : 1234567
n : 1234567
посмотреть его снова и дайте мне знать, если у вас есть какие-либо вопросы. Вы можете проверить против INT_MIN
и INT_MAX
если вы хотите привести результат к int
, но так же легко оставить ответ, как long
.
функции
как указано, это было бы гораздо более полезно в качестве функции. Вы можете переместить код в простую функцию преобразования и настроить основной код следующим образом:
...
#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);
}
...
Я бы сказал, что лучший способ-это не использовать scanf
для этого. По крайней мере, не используя числовые форматы.
вместо этого прочитайте его как строку, затем удалите запятые и, наконец,преобразовать в ряд.