简体   繁体   English

在C中,如何使用scanf扫描1,000,000忽略逗号

[英]In C, How to use scanf to scan in 1,000,000 ignoring the commas

在C中,在像1,000,000这样的数字上使用scanf时忽略逗号的最佳方法是什么?

I would say the best way is to not use scanf for this. 我想说最好的办法就是不要使用scanf At least not using any number formats. 至少不使用任何数字格式。

Instead read it as a string, then remove the commas, and finally convert to a number . 而是将其作为字符串读取,然后删除逗号,最后转换为数字

There are a number of ways to remove the commas (or any other character you want to skip). 有许多方法可以删除逗号(或任何其他要跳过的字符)。 One of the easiest (and most flexible) is to simply walk two pointers down the input string shifting all the digits together ignoring the commas. 最简单(也是最灵活)之一就是简单地将两个指针向下移动输入字符串,将所有数字移到一起,忽略逗号。 (you must be sure to nul-terminate after the final digit). (你必须确保在最后一位数后终止 )。

An example would be: 一个例子是:

#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;
}

( note: xstrtol simply provides error checking on the conversion of string to long ) 注意: xstrtol只是提供了将string转换为long错误检查)

Use/Output 使用/输出

$ ./bin/nwithcomma
enter number with ',': 1,234,567

 string : 1234567
 n      : 1234567

Look it over and let me know if you have any questions. 仔细看看,如果您有任何疑问,请告诉我。 You can check against INT_MIN and INT_MAX if you want to cast the result to int , but it is just as easy to leave the answer as a long . 如果要将结果转换为int ,可以检查INT_MININT_MAX ,但是将答案保留为long很容易。

As a Function 作为一种功能

As pointed out, it would be far more useful as a function. 正如所指出的那样,它作为一种功能将更有用。 You can move the code to a simple conversion function, and adjust the main code as follows: 您可以将代码移动到简单的转换函数,并按如下方式调整主代码:

...
#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);
}
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM