根据分隔符拆分一串整数并转换为int类型?

Spilt a string of integers based on delimiter and convert to int type?

我正在编写一个程序,它将一个有序数字对文件作为输入,我想拆分这些有序数字对并将它们转换为整数以存储在数组中。

文件可能是这样的:

0 1
1 4
9 11
12 45

我想写一个接受行的函数,(假设在程序的另一部分已经以 null 终止),拆分 space 处的数字,然后将它们存储在整数数组中尺寸二:

 int *store = malloc(2 * sizeof(store));

我已经研究了 strtok,但我说它不是线程安全的,因此不是这种情况下的最佳选择,我说得对吗?此外,它不会将数字转换为整数,这是函数也需要具备的东西。

我该如何解决这个问题?

也许这是一个解决方案:

gets(str, 80, fp); // get a line
sscanf(str, "%d %d", &store[0], &store[1]); // read numbers from that line

如果您想将未知数量的有序对读入有序对数组,有多种方法可以实现。如评论中所述,如果您可以 保证 每行总是有 2 个整数,那么接近 reading/converting 整数值的最简单方法可能是 fscanf

(当你在每一行上都有完全相同的数据格式时,我建议 fscanf 超过 fgets 只有 次之一 sscanf, 然后只是为了简化例子)

当您有未知数量的元素要读取时,基本方案是为一些合理预期的数字对分配内存,然后根据需要 realloc。由于您正在读取有序对,因此可以通过为 指向双整数数组的指针 分配存储来简化过程。例如,您的 ordered-pairs op 数组声明如下:

    int (*op)[2] = NULL;

您可以为 MXLINE 对数分配存储空间:

    op = calloc (MXLINE, sizeof *op);

(你可以使用malloccalloc来分配)

分配初始内存来保存有序对后,您只需读取包含两个十进制转换说明符(例如 "%d %d")的格式字符串的每一行,然后让 fscanf 执行转换。您必须验证 2 转换是否发生,然后将值存储在数组中。

记录您添加的对数 运行ning,这样您就可以在达到限制时 realloc。一个例子如下所示。不要忘记在不再需要时释放所有内存,并且 运行 您的代码通过内存检查器来验证您对动态分配内存的使用。

使用您的数据文件将所有内容放在一个简短的示例中,您可以执行如下操作。注意:程序将从命令行第一个参数给出的文件中读取(如果没有给出文件名,则默认从 stdin 读取):

#include <stdio.h>
#include <stdlib.h>

#define MXLINE 2

int main (int argc, char **argv) {

    int i, idx = 0, mxline = MXLINE;
    int (*op)[2] = NULL;
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    /* allocate/validate initial memory */
    if (!(op = calloc (MXLINE, sizeof *op))) {
        fprintf (stderr, "error: virtual memory exhausted.\n");
        return 1;
    }

    /* read each ordered pair into 'op' array */
    while (fscanf (fp, "%d %d", &op[idx][0], &op[idx][1]) == 2) {
        if (++idx == mxline) { /* realloc when limit reached */
            void *tmp = realloc (op, sizeof *op * mxline * 2);
            if (!tmp) { /* validate reallocation */
                fprintf (stderr, "error: realloc failed.\n");
                break;
            }
            op = tmp;    /* assign reallocated pointer to op */
            mxline *= 2; /* update line allocation limit */
        }
    }

    for (i = 0; i < idx; i++) /* show ordered pairs */
        printf ("pair[%3d] %3d : %3d\n", i, op[i][0], op[i][1]);

    free (op);  /* free allocated memory */

    if (fp != stdin)    /* close file if not stdin */
        fclose (fp);

    return 0;
}

例子Use/Output

$ ./bin/array_ptr2array <dat/orderedpairs.txt
pair[  0]   0 :   1
pair[  1]   1 :   4
pair[  2]   9 :  11
pair[  3]  12 :  45

Memory/Error检查

不要忘记验证您对动态分配内存的使用以及您在不再需要时释放所有内存:

$ valgrind ./bin/array_ptr2array <dat/orderedpairs.txt
==8107== Memcheck, a memory error detector
==8107== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8107== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==8107== Command: ./bin/array_ptr2array
==8107==
pair[  0]   0 :   1
pair[  1]   1 :   4
pair[  2]   9 :  11
pair[  3]  12 :  45
==8107==
==8107== HEAP SUMMARY:
==8107==     in use at exit: 0 bytes in 0 blocks
==8107==   total heap usage: 3 allocs, 3 frees, 112 bytes allocated
==8107==
==8107== All heap blocks were freed -- no leaks are possible
==8107==
==8107== For counts of detected and suppressed errors, rerun with: -v
==8107== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)

(注意: 初始分配是针对 MXLINE (2) 对。故意这样做是为了强制重新分配。在现实世界中你将希望最大限度地减少必须分配内存的次数。因此,如果您认为可以有 20 对左右,请将初始分配设置为 2432 对或任何您最合理的猜测您将拥有的号码(再加上一对夫妇))

仔细阅读,如果您有任何问题,请告诉我。