【问题标题】:Count and get integers from a string using C使用 C 计算并从字符串中获取整数
【发布时间】:2017-08-02 00:13:08
【问题描述】:

我正在自学 C 编程。 我正在尝试计算给定字符串中存在的以空格分隔的 int 数。

表达式: 输入str =“1 2 11 84384 0 212” 输出应为:1、2、11、84384、0、212 总整数 = 6

当我尝试时。它给了我所有有意义的数字作为输出,因为我在这里没有使用正确的方法。

我知道在 python 中我可以使用 str.split (" ") 函数,它可以很快完成我的工作。

但我想在 C 中尝试类似的东西。尝试创建自己的拆分方法。

#include <stdio.h>
#include <string.h>
void count_get_ints(const char *data) {
    int buf[10000];
    int cnt = 0, j=0;
    for (int i=0; i<strlen(data); i++) {
        if (isspace(data[i] == false)
            buf[j] = data[i]-'0';
            j++;
    }
    printf("%d", j);

}

// when I check the buffer it includes all the digits of the numbers.
// i.e for my example.
// buf = {1,2,1,1,8,4,3,8,4,0,2,1,2} 
// I want buf to be following 
// buf = {1,2,11,84384,0,212}

我知道这不是解决此问题的正确方法。一种跟踪 prev 并使用遇到的非空格数字动态创建内存的方法。 但我不确定这种方法是否有帮助。

【问题讨论】:

  • 如果您有 1 位整数,您的方法可能有效,但您的整数跨越多个符号。作为提示,您需要找出整数在字符串中开始的位置。然后您可以使用strtol 函数将字符串开头的部分转换为整数。

标签: c string


【解决方案1】:

您希望逐步建立您的号码,直到您点击一个空格,然后将其放入数组中。您可以通过乘以 10 然后每次添加下一位来做到这一点。

void count_get_ints(const char *data) {
    int buf[10000];
    int j = 0;
    int current_number = 0;

    // Move this outside the loop to eliminate recalculating the length each time
    int total_length = strlen(data); 
    for (int i=0; i <= total_length; i++) {
        // Go up to 1 character past the length so you 
        //   capture the last number as well
        if (i == total_length || isspace(data[i])) {
            // Save the number, and reset it
            buf[j++] = current_number;
            current_number = 0;
        }
        else {
            current_number *= 10;
            current_number += data[i] - '0';
        }
    }
}

【讨论】:

    【解决方案2】:

    我认为strtok 将提供更简洁的解决方案,除非您真的想遍历字符串中的每个字符。很久没做C了,下面代码中的任何错误请见谅,希望能给你正确的思路。

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        char str[19] = "1 2 11 84384 0 212";
        const char s[2] = " ";
        char *token;
        int total;
    
        total = 0;
        token = strtok(str, s);
    
        while (token != NULL) {
            printf("%s\n", token);
            total += atoi(token);
            token = strtok(NULL, s);
        }
        printf("%d\n", total);
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      您可以通过c-'0' 来检查每个字符的ascii 值。如果它在 [0,9] 之间,那么它是一个整数。通过拥有一个状态变量,当您通过检查给定字符是否为多个空格而在整数内时,您可以通过忽略空格来跟踪计数。另外,您不需要缓冲区,如果数据大于 10,000,并且您写入通过缓冲区的末尾会发生什么情况?,未定义的行为将会发生。此解决方案不需要缓冲区。

      编辑,解决方案现在打印字符串中的整数

      void count_get_ints(const char *data) {
         int count = 0;
         int state = 0;
         int start = 0;
         int end = 0;
         for(int i = 0; i<strlen(data); i++){
            int ascii = data[i]-'0';
            if(ascii >= 0 && ascii <= 9){
               if(state == 0){
                  start = i;
               }
               state = 1;
            }else{
               //Detected a whitespace
               if(state == 1){
                  count++;
                  state = 0;
                  end = i;
                  //Print the integer from the start to end spot in data
                  for(int j = start; j<end; j++){
                      printf("%c",data[j]);
                  }
                  printf(" ");
               }
            }
         }
         //Check end
         if(state == 1){
            count++;
            for(int j = start; j<strlen(data); j++){
                printf("%c",data[j]);
            }
            printf(" ");
         }
         printf("Number of integers %d\n",count);
      }
      

      【讨论】:

        【解决方案4】:

        我相信执行此操作的标准方法是使用 sscanf 使用 %n 格式说明符来跟踪读取了多少字符串。

        你可以从一个大数组开始读入-

        int array[100];
        

        然后您可以继续从字符串中读取整数,直到您无法再读取或读取完 100。

        int total = 0;
        int cont = 0;
        int ret = 1;
        while(ret == 1 && total < 100) {
            ret = sscanf(input, "%d%n", &array[total++], &cont);
            input += cont;
        }
        total--;
        printf("Total read = %d\n", total);
        

        array 包含所有读取的数字。

        这里是DEMO

        【讨论】:

          【解决方案5】:

          使用strtol的示例

          #include <stdio.h>
          #include <stdlib.h>
          #include <limits.h>
          #include <errno.h>
          #include <ctype.h>
          
          int count_get_ints(int output[], int output_size, const char *input) {
              const char *p = input;
              int cnt;
          
              for(cnt = 0; cnt < output_size && *p; ++cnt){
                  char *endp;
                  long n;
                  errno = 0;
                  n = strtol(p, &endp, 10);
                  if(errno == 0 && (isspace((unsigned char)*endp) || !*endp) && INT_MIN <= n && n <= INT_MAX){
                      output[cnt] = n;
                      while(isspace((unsigned char)*endp))
                          ++endp;//skip spaces
                      p = endp;//next parse point
                  } else {
                      fprintf(stderr, "invalid input '%s' in %s\n", p, __func__);
                      break;
                  }
              }
              return cnt;
          }
          
          int main(void) {
              const char *input = "1 2 11 84384 0 212";
              int data[10000];
              int n = sizeof(data)/sizeof(*data);//number of elements of data
          
              n = count_get_ints(data, n, input);
              for(int i = 0; i < n; ++i){
                  if(i)
                      printf(", ");
                  printf("%d", data[i]);
              }
              puts("");
          }
          

          【讨论】:

            【解决方案6】:

            假设您的字符串中没有任何非数字,您只需计算空格数 + 1 即可找到字符串中的整数个数,如下伪代码所示:

            for(i = 0; i < length of string; i++) {
               if (string x[i] == " ") {
                  Add y to the list of strings
                  string y = "";
                  counter++;
               }
            
               string y += string x[i]
            }
            
            numberOfIntegers =  counter + 1;
            

            此外,这会读取空格之间的数据。请记住,这是伪代码,因此语法不同。

            【讨论】:

            • 关于从字符串中读取实际空格分隔数字的问题。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-03-14
            • 2011-01-22
            相关资源
            最近更新 更多