-1

我正在尝试读取一个包含我的代码坐标值的文件。

我的问题是,如何使数组大小足够大以包含将来添加到文件中的内容?

以下是我的代码;当我将数组的大小设置为 905 时,我的循环将继续,直到空间被填满。这是为什么?

FILE.txt

S (60,70)(200,200)
S (30,40)(100,200)
S (10,20)(80,10)
S (60,400)(700,200)
S (160,70)(240,20)
S (160,70)(240,20)
S (160,70)(240,20)

我的代码:

#include <stdio.h>
int a;
int b;
int c;
int d;
int data[905][4];
int main ( int argc, char *argv[] )
{
    if ( argc != 2 ) /* argc should be 2 for correct execution */
    {
        /* We print argv[0] assuming it is the program name */
        printf( "usage: %s filename", argv[0] );
    }
    else 
    {
        // We assume argv[1] is a filename to open
        FILE *file = fopen( argv[1], "r" );

        /* fopen returns 0, the NULL pointer, on failure */
        if ( file == 0 )
        {
            printf( "Could not open file\n" );
        }
        else 
        {
            int j=0;int count=1
            for (j=0; j < count; j++) 
            {    
                fscanf(file, "S (%d,%d)(%d,%d)", &a, &b, &c, &d);

                printf("%d,%d,%d,%d\n",a, b, c, d);
                count++
            }             

            fclose( file );
        }
    }
}
4

2 回答 2

1

int j=0;int count=1
for (j=0; j < count; j++) 
{

     fscanf(file, "S (%d,%d)(%d,%d)", &a, &b, &c, &d);

     printf("%d,%d,%d,%d\n",a, b, c, d);
     count++
}

你有一个循环保持countj直到count++溢出大一并且给你未定义的行为。编译器很可能会忽略循环控制并使其成为无限循环,因为它可能会假设没有发生未定义的行为。

因此,循环尝试从文件中读取值而没有结束,或者至少在很长一段时间内。当到达文件末尾时,fscanf不会读取任何值,但由于您不检查其返回值,因此不会停止循环。为避免这种情况,您可以执行类似的操作

if (fscanf(file, "S (%d,%d)(%d,%d)", &a, &b, &c, &d) < 4) {
    break;
}

这样循环在到达文件末尾时结束,或者发生一些输入错误。

关于

如何使数组大小足够大以包含将来添加到文件中的内容?

然后,您不应使用具有静态定义维度的数组,而应使用分配空间malloc

int (*data)[4] = malloc(num_rows * sizeof *data);

当你需要更多时,

int (*temp)[4] = realloc(data, new_num_rows * sizeof *data);
if (temp == NULL) {
    // reallocation failed, handle it or exit
} else {
    data = temp;
}

realloc更大的内存块。

于 2012-09-22T21:01:44.627 回答
1

为此,您将需要使用mallocrealloc函数<stdlib.h>。基本思路是先分配一定的空间,等发现不够大的时候再放大数组。

如果您使用结构数组而不是数组数组,这将使生活更轻松:

struct segment { int x0, y0, x1, y1; };

然后你做这样的事情:

size_t nsegs = 0, segs_allocated = 10;
struct segment *segs = malloc(segs_allocated * sizeof(struct segment));
if (!segs) abort();

while (getline(&line, &linesz, stdin) >= 0)
{
    if (!parse_line(&segs[nsegs], line)) continue;
    nsegs++;
    if (nsegs == segs_allocated)
    {
        segs_allocated *= 2;
        segs = realloc(segs, segs_allocated * sizeof(struct segment));
        if (!segs) abort();
     }
}

强制性切线评论:忘记你听说过的fscanf。这比它的价值要麻烦得多。读取整行getline(如果没有,实现起来并不难),使用手动编码的解析器从行中提取单独的数字字符串,然后使用 、 或适当的将它们转换为strtol机器strtoul整数strtod

于 2012-09-22T21:03:22.980 回答