c++ - 解析字符串以获取逗号分隔的整数字符对

标签 c++ c string data-structures split

我正在做一个项目,在这个项目中,我得到了一个以这种格式的标题开头的文件:a1,b3,t11, 2,,5,\3,*4,344,00,。它始终是单个 ASCII 字符的序列,后跟一个用逗号分隔的整数,序列始终以 00, 结尾。

基本上,我要做的是通过这个并将每个字符/整数对放入我拥有的数据类型中,该数据类型将这两个作为参数并制作它们的 vector 。例如,我在上面给出的 header 将是一个带有 ('a',1), ('b',3),('t',11),(',',5)(' ' ,2),('\',3),('*',4),('3',44) 作为元素。

我只是无法解析它。到目前为止,我已经:

  • 从我的文本文件中提取标题,从第一个字符一直到标题结束的“,00”之前。我可以获得字符串格式的标题字符串或作为字符 vector (以更容易解析的为准)
  • 尝试使用 sscanf 解析下一个字符和下一个 int,然后将它们添加到我的 vector 中,然后使用子字符串删除我已经分析过的字符串部分(这很困惑,并没有让我明白正确的结果)
  • 尝试将字符串作为 vector 并检查每个元素以查看它是整数、字符还是逗号并采取相应的行动,但这不适用于多位整数或当字符本身是一个 int

    我知道我可以很容易地根据逗号拆分我的字符串,但我不确定如何做到这一点,并且仍然将整数从字符中拆分出来,同时保留两者并考虑我需要将其视为字符的整数。

    任何建议或有用的标准库或字符串函数将不胜感激。

  • 最佳答案

    在许多可能性中,一种可能性是将数据存储在结构中。这使用结构数组,但可以根据需要使用 mallocrealloc 分配结构。
    可以使用指针和 strtol 来解析字符串,后者将解析整数并给出指向整数后面字符的指针。该指针可以提前用于下一次迭代以获取 ASCII 字符和整数。

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define SIZE 100
    
    struct pair {
        char ascii;
        int  integer;
    };
    
    int main( void) {
        char input[] = "a1,b3,!0,t11, 2,,5,\\3,*4,34400,";
        char *pt = input;//start with pt pointing to first character of input
        char *end = input;
        int each = 0;
        int loop = 0;
        int length = 0;
        struct pair pairs[SIZE] = { { '\0', 0}};
    
        //assuming input will always end in 00, ( or ,00,)
        //remove those three ( or 4 ??) characters
        length = strlen ( input);
        if ( length > 3) {
            input[length - 3] = '\0';
        }
        for ( each = 0; each < SIZE; each++) {
            //get the ASCII character and advance one character
            pairs[each].ascii = *pt;
            pt++;
            //get the integer
            pairs[each].integer = strtol ( pt, &end, 10);
            //end==pt indicates the expected integer is missing
            if ( end == pt) {
                printf ( "expected an integer\n");
                break;
            }
            //at the end of the string?
            if ( *end == '\0') {
                //if there are elements remaining, add one to each as one more was used
                if ( each < SIZE - 1) {
                    each++;
                }
                break;
            }
            //the character following the integer should be a comma
            if ( *end != ',') {
                //if there are elements remaining, add one to each as one more was used
                if ( each < SIZE - 1) {
                    each++;
                }
                printf ( "format problem\n");
                break;
            }
            //for the next iteration, advance pt by one character past end
            pt = end + 1;
        }
        //loop through and print the used structures
        for ( loop = 0; loop < each; loop++) {
            printf ( "ascii[%d] = %c   ", loop, pairs[loop].ascii);
            printf ( "integer[%d] = %d\n", loop, pairs[loop].integer);
        }
    
        return 0;
    }
    

    另一种选择是使用动态分配。
    这也使用 sscanf 来解析输入。 %n 将捕获扫描处理的字符数。然后可以使用 offsetadd 变量遍历输入。最后一次扫描只会捕获 ascii 字符和整数,sscanf 的返回值为 2。

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    struct pair {
        char ascii;
        int  integer;
    };
    
    int main( void) {
        char input[] = "a1,b3,!0,t11, 2,,5,\\3,*4,34400,";
        char comma = '\0';
        char ascii = '\0';
        int integer = 0;
        int result = 0;
        int loop = 0;
        int length = 0;
        int used = 0;
        int add = 0;
        int offset = 0;
        struct pair *pairs = NULL;//so realloc will work on first call
        struct pair *temp = NULL;
    
        //assuming input will always end in 00, ( or ,00,)
        //remove those three ( or 4 ??) characters
        length = strlen ( input);
        if ( length > 3) {
            input[length - 3] = '\0';
        }
        while ( ( result = sscanf ( &input[offset], "%c%d%c%n"
        , &ascii, &integer, &comma, &add)) >= 2) {//the last scan will only get two items
            if ( ( temp = realloc ( pairs, ( used + 1) * sizeof ( *pairs))) == NULL) {
                fprintf ( stderr, "problem allocating\n");
                break;
            }
            pairs = temp;
    
            pairs[used].ascii = ascii;
            pairs[used].integer = integer;
            //one more element was used
            used++;
            //the character following the integer should be a comma
            if ( result == 3 && comma != ',') {
                printf ( "format problem\n");
                break;
            }
            //for the next iteration, add to offset
            offset += add;
        }
        for ( loop = 0; loop < used; loop++) {
            printf ( "ascii[%d] = %c   ", loop, pairs[loop].ascii);
            printf ( "value[%d] = %d\n", loop, pairs[loop].integer);
        }
    
        free ( pairs);
    
        return 0;
    }
    

    关于c++ - 解析字符串以获取逗号分隔的整数字符对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40571339/

    相关文章:

    c++ - 如何在自定义 OleDB 驱动程序中显示浏览按钮

    python - 传递给 C API 的参数对于 Python 中的子线程没有意义

    java - 实现我自己的 indexOf 方法的递归版本

    ruby-on-rails - 如何删除字符串末尾的所有 `/` 字符?

    c++ - 如何找到等于总和的子序列的最大子集的大小

    c++ - 试图更好地理解 std::forward、std::move

    c++ - 隐式生成的成员和 noexcept

    python - Python 中以 null 结尾的字符串转换为 Int

    c - Windows 中的内存分配限制 + 我是否正确计算?

    c++ - 从 3 个 vector 中删除重复项