使用struct和realloc验证文件

时间:2015-11-19 06:02:00

标签: c struct malloc realloc

我这里有一个代码需要验证txt文件并过滤数据。我需要为我的代码使用struct和realloc。

这里的想法是先读取txt文件并将其存储在数组中。之后,它将根据以下条件过滤掉数据。符合条件的那些将转到data_1.txt,其他将转到error.txt。

我收到以下错误的结构,我不确定它。

error C2440: '=' : cannot convert from 'void *' to 'Validation *'
     Conversion from 'void*' to pointer to non-'void' requires an explicit cast
error C2062: type 'void' unexpected
error C2065: 'src' : undeclared identifier
error C2065: 'dest' : undeclared identifier
error C2065: 'type' : undeclared identifier
error C2065: 'port' : undeclared identifier

示例源文件:

9001:0002:9003:0021
0001:0010:0003:0021
8001:0002:8002:0080

源代码:

#include <stdio.h>
#include <stdlib.h>             //for exit (1)
#include <malloc.h>

struct Validation {
    int src;
    int dest;
    int type;
    int port;
    char data[50];
};

int main ()
{
    struct Validation *array;
    int option;

    FILE *inFile;               //file handle or pointer

    char filename[100];
    char test;
    int count = 0;              //keep track number of records

    int n1 = 0;                 //keep track number of correct records
    int n2 = 0;                 //keep track number of error records

    array = (struct Validation *) malloc (sizeof (struct Validation));

    do {
        printf ("Enter filename: ");
        scanf ("%s", filename);
        printf ("Processing filename %s ...\n", filename);

        inFile = fopen (filename, "r");
        if (inFile == NULL)     //check if file handler is invalid
        {
            printf ("Could not open file %s\n", filename);
            exit (1);           //error status code
        }

        test = fscanf (inFile, "%d:%d:%d:%d:",
                    &array[count].src, array[count].dest,
                    array[count].type, array[count].port);
        while (test != EOF) {
            count++;
            array = realloc (array, (count + 1) * sizeof (struct Validation));

            test = fscanf (inFile, "%d:%d:%d:%d:",
                        &array[count].src, array[count].dest,
                        array[count].type, array[count].port);
        }
    }

    void save (int, struct Validation *);
    FILE *outFile;
    FILE *errorFile;
    int i;

    outFile = fopen ("data_1.txt", "wt");
    errorFile = fopen ("data_error.txt", "wt");
    if (outFile == NULL)        //check if file handler is invalid
    {
        printf ("Could not write to file \n", filename);
        exit (1);
    }

    if (count > 0) {
        printf ("Viewing all records: ", count);
        for (i = 0; i < count;
            i++, src >= 1 && src <= 1024 && dest >= 1 && dest <= 1024
            && type >= 1 && type <= 10 && port >= 1 && port <= 1024) {
            fprintf (outFile, "%d %d %d %d", 
                    (i + 1), 
                    array[i].src,
                    array[i].dest, 
                    array[i].type, 
                    array[i].port);
            n1++;
        }
    } else {
        fprintf (errorFile, "%d %d %d %d",
                array[i].src, array[i].dest, array[i].type, array[i].port);
        n2++;
    }

    fclose (errorFile);
    fclose (outFile);
    fclose (inFile);            //must always close file once done

    free (array);

    return 0;
}

1 个答案:

答案 0 :(得分:3)

对于此程序中的所有错误,我只能得出结论,您用于学习C的资源不起作用;它会教你各种错误,包括阻止你的程序编译的那种错误以及妨碍程序正常运行的错误。我建议你阅读K&amp; R第二版并进行练习,然后再继续学习这个课程。

首先,您的项目包含一些严重的语法错误,您在修复缩进时会发现这些错误。如果您不知道该怎么做,请考虑学习this wiki page on indent styles

后四个错误都在这一行:

for (i = 0; i < count; i++, src >= 1 && src <= 1024 && dest >= 1 && dest <= 1024 && type >= 1 && type <= 10 && port >= 1 && port <= 1024)
                          ^----------

首先,您的错误告诉您srcdesttypeport未声明。也许您打算写array[i].srcarray[i].destarray[i].typearray[i].port ......

我指点的逗号可能并不代表你的想法。即使您修复了此行中的错误,该逗号之后的所有内容都根本不会影响此代码,因此您的循环有效:

for (i = 0; i < count; i++)

我只能冒险猜测,但是for(预测试)循环可能不适合您的需要,而您应该使用if (part_of_test) do { ... } while (test);成语?也许这是过分的,你可以仅使用do { ... } while (test);白痴来编写所需的功能。

while (test != EOF)

这个循环也是错误的。如果要确保从inFile正确读取四个十进制数字整数,则需要确保test等于4,这与确保test不同1}}不等于EOF。例如:

while (test == 4)

继续,您似乎正在尝试将C代码编译为C ++。

虽然某些C代码在C ++中也是有效的,但您遇到的C代码示例在C ++中并不有效。

也就是说,C ++不会向C语言提供与void *的隐式转换。

您应始终使用C编译器编译C代码,原因如下:

  • 您不需要使用C ++编译器编译C代码。
  • 您错过了C ++的最佳部分。
  • 你错过了C的最佳部分。

人们尝试使用C ++编译器编译C代码的唯一原因是他们期望在C ++项目中使用他们的C代码。但是,这是不必要的,因为您通常可以使用C编译器编译C代码,使用C ++编译器编译C ++代码,然后将两者链接在一起。例如:

gcc -c c_code.c
g++ -c cpp_code.cpp
gcc cpp_library.o c_library.o

如果您正在使用Microsoft Visual Studio,请将您的C源代码分成不同的项目并浏览项目设置,以查找&#34;编译为C代码&#34;选项。如果你的项目只是C,你可以忽略本段的其余部分......否则你的项目是混合C和C ++。在您浏览的同时,请密切关注&#34;链接&#34;和&#34;项目依赖&#34;设置;您将要将C项目设置为C ++项目的依赖项。您可能还想介绍一些&#34;链接目录&#34; (或路径,我忘记了精确的术语)和/或&#34;包含目录&#34;。

在C ++中,使用void *指针通常是个坏主意(你应该probably use new instead of malloc)。更不用说,您应该避免使用*scanf系列函数。那些专门用C ++编程的人通常会对这些实践感到畏缩,因为模板和运算符重载实际上消除了它们的所有有效用例,使得相应的C ++代码不易出错并且可以直接读写。

在C中,明确投射void *总是一个坏主意(并且你应该消除当前使用的void *投射),正如the answer to this question所解释的那样。那些专门用C语言编程的人会在不必要的样板上畏缩,这可能会引入错误。