【问题标题】:Convert a set of chars to int from a file将一组字符从文件转换为 int
【发布时间】:2011-05-06 07:28:01
【问题描述】:

我正在阅读:

22:5412:99:00 (...)

来自使用(ch=fgetc(fp)) != EOF 的文本文件,因为我没有只有这些数字要读取。 使用if(ch >= 48 && ch <= 57) 识别数字很容易,但问题是我想将这些数字 22、5412 放入一个整数数组中。但是,当我读取一个字符时,它会读取部分数字,因为每个数字都是字符。 它得到 2(而不是我想要的 22),并且在下一次迭代中读取另一个 2。如何将每组数字保存到它自己的整数中?

希望我说的够清楚了,谢谢!

【问题讨论】:

  • 首选isdigit(ch)来识别数字。
  • 哦,这是一个很好的提示,谢谢。

标签: c input integer char


【解决方案1】:

您需要将数字存储为字符串或 char* 并使用 atoi 将其实际转换为数字。 http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

【讨论】:

    【解决方案2】:

    我的想法是读取每个char,如果是数字,则将其附加到缓冲区。每当我们得到一个非数字时,我们只需使用sscanf 将缓冲区的内容作为字符串读取,然后清除缓冲区以获取下一个值。

    #include <stdio.h>
    #include <stdlib.h>
    
    int read_buffer(char* buffer, int* sz)
    {
        int ret;
        if (*sz==0) return 0;
        buffer[*sz]='\0'; //end the string
        sscanf(buffer,"%d", &ret); //read the contents into an int
        *sz=0; // clear the buffer
        return ret;
    }
    
    int main()
    {
        char buffer[1000];
        int sz=0;
        char ch;
        FILE* input=fopen("input.txt","r");
        // "input.txt" contains 22:5412:99:00
        while ((ch=fgetc(input))!=EOF)
        {
            int number;
            if (isdigit(ch))
            {
                buffer[sz++]=ch; // append to buffer
            }
            else
            {
                printf("Got %d\n",read_buffer(buffer,&sz)); // read contents of buffer and clear it
            }
        }
        if (sz) // check if EOF occured while we were reading a number
            printf("Got %d\n",read_buffer(buffer,&sz)); 
        fclose(input);
        return 0;
    }
    

    【讨论】:

    • 哦,不知道 sscanf 可以做到这一点。这比 atoi 更受欢迎吗?
    • @Queops:不确定大师和学究更喜欢哪一个。我通常使用sscanf,因为它更通用,可以处理/提取嵌入无关字符中的值,并一次从同一个字符串中获取多个整数,所有这些都使用格式字符串。
    • atoi 不做任何错误处理。 sscanf 做了一些(也许你应该检查返回值)。但是唯一能检测溢出的函数(即,检测像 99999999999999999999999 之类的数字何时不能适合 long 或 long long 是 strtol/strtoll 函数。它还有一种方法来获取指向第一个非数字字符的指针所以你可以检测后缀。
    【解决方案3】:

    假设您的模式是 NN:NNNN:NN:NN 类型,解析分隔符,将字符输入缓冲区:

    int idx = 0, nIdx = 1;
    int firstN, secondN, thirdN, fourthN;
    char buf[5];
    ...
    while ((ch=fgetc(fp)) != EOF) {
        if (ch != ':') {
            buf[idx++] = ch;
        } 
        else {
            buf[idx] = '\0';
            idx = 0;
            switch (nIdx++): {
                case 1: firstN = atoi(buf); break;
                case 2: secondN = atoi(buf); break;
                case 3: thirdN = atoi(buf); break;
            }
        }
    }
    buf[idx] = '\0';
    fourthN = atoi(buf);
    ...
    

    【讨论】:

    • 应该说完全没有模式。
    【解决方案4】:

    我在上一篇文章中做了一个完整的程序——以及一些测试:-​​)

    #include <ctype.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    /* fill `array` with at most `siz` values read from the stream `fp` */
    /* return the number of elements read */
    size_t fillarray(int *array, size_t siz, FILE *fp) {
      int ch;
      size_t curr = 0;
      int advance_index = 0;
      while ((ch = fgetc(fp)) != EOF) {
        if (isdigit((unsigned char)ch)) {
          array[curr] *= 10;
          array[curr] += ch - '0';
          advance_index = 1;
        } else {
          if (advance_index) {
            advance_index = 0;
            curr++;
            if (curr == siz) { /* array is full */
              break;
            }
          }
        }
      }
      return curr + advance_index;
    }
    
    int main(void) {
      int array[1000] = {0};
      int n, k;
    
      n = fillarray(array, 1000, stdin);
      if (n > 0) {
        printf("%d values read:\n", n);
        for (k=0; k<n; k++) {
          printf(" %d", array[k]);
        }
        puts("");
      } else {
        fprintf(stderr, "no data read\n");
      }
      return 0;
    }
    

    还有试运行

    $ ./a.out 24555:76423 foobar 76235 jgfs(8) jhg x86-64 passw0rd RS232 [CTRL+D] 读取 8 个值: 24555 76423 76235 8 86 64 0 232

    【讨论】:

      猜你喜欢
      • 2020-05-12
      • 2012-03-24
      • 1970-01-01
      • 2021-12-21
      • 2016-08-14
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多