将输入文件分为两个不同的二维数组

时间:2018-07-08 17:31:45

标签: c arrays

我目前正在做一个作业,要求我获取一个输入文件,将其分离并将内容存储到两个不同的数组中。

Registration

假设输入文件如下所示:

/**
 * The accessors to append to the model's array form.
 *
 * @var array
 */
protected $appends = ['totalPrice'];

其中1之前的第一个值存储在名为line的数组中,空白行之后的行需要放入DataMem数组中。

有人可以指出我该如何做的方向吗?我可以正确地填充数组行,但是我很难在那一刻停止填充,然后将其余文件填充到数组datamem中。

谢谢

2 个答案:

答案 0 :(得分:2)

几个问题;一个是(就像某些程序员的老兄所说的)是您执行i ++,所以对line [i] ==“”的测试引用了未初始化的内存。

您还有一个问题,就是无法使用==比较字符串,必须使用strcmp()。问题是C中的字符串实际上是指针,所以

char *foo = "Hello";
char *bar = "Hello";
if (foo == bar)
    printf("This will never print out\n")

不会执行您期望的操作-您将永远不会看到打印输出,因为它将(可能)编译为foo将被设置为指向内存中具有“ H”的地址(例如0x1000)在0x1000中为',在0x1001中为'e',依此类推,在0x1004中最高为'o',在0x1005中最高为'\ 0'。 bar变量将指向其他地址(例如0x2000),该地址也将包含字符串“ Hello”。因此,尽管两个字符串相同,但是if测试实际上是在测试if (0x1000 == 0x2000),这将失败-您需要执行if (!strcmp(foo, bar))才能实际测试内容。

[注:此示例实际上有缺陷,因为大多数现代编译器只会在只读内存中创建一个“ Hello”字符串的实例,然后将两个变量都指向该实例,因此在这种情况下,if测试实际上可以工作。但是您不应该依赖于此,并且它在一般情况下绝对不成立。]

您在第[i]行的测试也看起来不正确,因为我怀疑您要复制以空格开头的字符串,而不是完全是“”的字符串,因此我怀疑您实际上是在第[i]行测试0]。但是我不确定是否不知道您的任务。

您对DataMem的声明也是不正确的-您已将其声明为32个3字符条目,但是您正在向其中写入line [i],而line [i]是指针。您可能需要声明所有实例,使其足够大以容纳所需的整个字符串(假定该行可以容纳相同的21个字节)并复制到其中,或者需要将其声明为指针数组(char *DataMem[32]) 。您需要了解一个关键的区别:如果复制字符串,然后修改DataMem的字符串视图,则行的字符串视图不变。如果仅复制指针,则更改一个字符串会同时更改两个字符串(因为它们都指向完全相同的内存)。显然,复制字符串的速度较慢,并且会占用更多的内存(嗯,除了非常短的字符串以外)。

魔术数字也很糟糕。例如,我将做#define MAX_STRING_LEN 20而不是20和21,并在代码中使用它。 (记住将数组声明为足够大以容纳终止NIL的工作不错。但是fgets()已经意识到了这一必要,并且将最多读取少于一个字符,因此NIL有空间。您应该传递在21而不是20中)。另外,我将传递sizeof(line [i])作为fgets()的参数,而不是MAX_STRING_LEN(当然不是20)。这样,如果line [i]的大小改变了,代码仍然是正确的;如果传入与声明变量相同的维度,则有人可能会更改它而没有意识到他们也需要在此处进行更改。

最后,您需要在循环内部进行边界检查。如果输入的内容长于您为line []声明的100个条目,该怎么办?如果没有测试,则存在写超出变量边界的风险(这往往会导致真正难以发现的错误)。一个非常有用的宏是

#define NELEM(x)    (sizeof(x) / sizeof(*(x)))

您可以用来进行测试的

if (i >= NELEM(line)) {
    printf("Data overflow\n");
    exit(1);
}

因此您无需在代码内嵌入100(或用#define替换)。 (#define通过获取整个数据结构的大小并将其除以其中第一个元素的大小来工作。实际上所有的括号都是必需的。)

答案 1 :(得分:0)

#include <stdio.h>

int main()
{
    char DataMem[32][3];
    char line[100][21]; //Holds the value for each line in the input file

    for(int i = 0; fgets(line[i], 20, stdin) != NULL ; ++i)
    { 
        if('\r' == line[i][0] || '\n' == line[i][0]) {
            break;
        }

        printf("line[%d] = %s",i, line[i]);
    }

    for(int i = 0; fgets(DataMem[i], 20, stdin) != NULL ; ++i)
    {
        printf("DataMem[%d] = %s",i, DataMem[i]);
    }

    return 0;
}