【问题标题】:Code can't get an n-digit numbers from a string in C代码无法从 C 中的字符串中获取 n 位数字
【发布时间】:2016-12-01 04:29:11
【问题描述】:

我想问它怎么不能从字符串中获取整数

例如,这是我的代码:

int main() {
    char str[] = "ababbababa-1998";
    int nr = atoi(str);
    printf("%d\n", nr);
    return (EXIT_SUCCESS);
}

运行时打印出0而不是1998,我该如何解决?

【问题讨论】:

  • 你可以用ASCII码来计算
  • 不,我想将 1998 放入 nr 变量,而不是获取单个字符并进行转换
  • 你可以将所有的数字存储在一个 char[] 中,然后将其转换为整数。
  • 如果字符串格式是固定的(比如,“some_string-sume_number”),那么你可以使用 sscanf(string, "%s-%d", temp_str, &nr));
  • 可以,但可能会导致格式错误

标签: c string.h


【解决方案1】:

在您的情况下,您可以使用strtok

int main() {
    char str[] = "ababbababa-1998";
    char * const first_part = strtok(str, "-");
    if (first_part == NULL) {
        return 1;
    }
    char * const second_part = strtok(NULL, "-");
    if (second_part == NULL) {
        return 1;
    }
    int nr = atoi(second_part);
    printf("%d\n", nr);
    return 0;
}

您可以查看 Why is there no strtoi in stdlib.h? 进行错误检查 atoi。

【讨论】:

  • 你的 strtok(str) 用法有效吗?
  • 仅通过字符串查找第一个数字而不是依靠strtok 不是更健壮吗?
  • @MayurK 是的,我完全忘记了分隔符
  • @John3136 如果“-”之前的字符串中有一个数字,那将失败。我选择 strtok 来向他展示一种非常简单的解析器方法。
  • @Stargateur 我们没有提供足够的信息让我们知道我们是对的。
【解决方案2】:

继续往下走 str() 直到代码使用 strtol() 找到 something 数字。

int main() {
    char str[] = "ababbababa-1998";
    char *p = str; 

    char *endptr;
    while (*p) {
      long number = strtol(p, &endptr, 10);
      // Was conversion successful?
      if (endptr != p) {
        printf("%ld\n", number);
        return EXIT_SUCCESS;
      }
      p++;
    }
    puts("No conversion");
    return EXIT_FAILURE;
}

【讨论】:

    【解决方案3】:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    #define ASCII '0'
    
    int
    main(void) {
        char const str[] = "ababbababa-1998";
        int i, result = 0;
    
        for (i = 0; str[i]; i++) {
            if (isdigit(str[i])) {
                result *= 10;
                result += str[i] - ASCII;
            }
        }
    
        printf("number = %d\n", result);
    
        return 0;
    }
    

    【讨论】:

    • 可能值得使用更大的INITSIZE(例如128、256等)并使用静态缓冲区来避免mallocrealloc开销。 (动态分配没有任何问题,它只是增加了开销和复杂性)。您可能还想在找到数字后停止添加到nr,然后找到后续的非数字。 (例如,如果你有一个字符串 "aaaaa-1998aaaaa-1999")你可以为此目的使用一个简单的标志。只是想法,不是批评。
    • 是的,感谢@DavidC.Rankin 的建议,我认为这种方法太复杂了。我将编辑我的答案。
    • 复制大部分字符串只是为了将其转换为数字?垃圾! if (isdigit(array[i]) { total *= 10; total += array[i]; }
    • 已更改 @John3136。我忽略了这个简单的方法,干杯。
    • 显然应该是total += array[i] - '0'; - 只是注意到你已经这样做了。
    【解决方案4】:

    如果你想从一个字符串中提取所有的数字,你可以使用我创建的这个函数。

    您需要这些头文件才能使此功能正常工作。

    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    void getNumbers(char data[]) {
       int index = 0;
       char current;
    
       for( int i = 0; i < strlen(data); ++i ) {
          current = data[i];
          if (current >= 48 && current <= 57) {
             data[index++] = current;
          }
       }
        data[index] = '\0';
    }
    

    你可以像这样使用上面的函数。

    
    char foobar[] = "1A2B3C4D5E6F7G8H9I";
    
    getNumbers(foobar);
    
    printf("%s", foobar);
    
    

    上面的代码会输出123456789

    【讨论】:

      猜你喜欢
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      • 1970-01-01
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      相关资源
      最近更新 更多