c-控制台在读取文件和筛选数据字符数时卡住



运行下面的代码时没有出现任何错误。但在命令控制台上,它似乎被困在处理文件名xxxxx上,如下所示。

我可以问我如何使用if条件来过滤第67行中小于50的数据字符数,我尝试使用strlen(array[count].data) >= 1 && strlen(array[count].data) <= 50,但似乎不起作用?

输入文件名:testdata.txt

正在处理文件名testdata.txt…

示例源txt文件:

9001:0002:9003:0021:CLS
0001:0010:0003:0021:CLS
8001:0002:8002:0080:<HTML>
0001:4002:0002:0080:<BODY>
0004:0002:0002:0080:JHJKJBKHJBIUHBKBKHBKHHBKJBKJNKJKHHKUHKJLHBKHBKHBHBHBKHBHBHBHBBHHBHBJKJHKJHKJHKUHIUJ          

源代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>  
#include <stdlib.h> 
#include <malloc.h>
//struct definition
struct record{
int src;
int dest;
int type;
int port;
char data[100];
};

int main()
{
struct record *array;
FILE* inFile; //file handle or pointer
FILE* outFile;
FILE* errorFile;
char filename[100];
int count = 0;  //keep track of number of records in memory
int i = 0;
int test;
int n1 = 0; //keep track number of correct records
int n2 = 0; //keep track number of error records
array = (struct record *) malloc(sizeof(struct record));
//User to enter filename
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 %sn", 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);
fgets(array[count].data, 100, inFile);
while (test != EOF){
    count++;
    array = (struct record *) realloc(array, (count + 1)*sizeof(struct record));
    test = fscanf(inFile, "%d:%d:%d:%d:%s",
        &array[count].src, &array[count].dest, &array[count].type, &array[count].port, &array[count].data);
}
fclose(inFile); //must always close file once done
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++){
        if (array[count].src >= 1 && array[count].src <= 1024 && array[count].dest >= 1 && array[count].dest <= 1024 && array[count].type >= 1 && array[count].type <= 10 && array[count].port >= 1 && array[count].port <= 1024)
            n1++;
            fprintf(outFile, "%d %d %d %d",
            (i + 1),
            array[count].src,
            array[count].dest,
            array[count].type,
            array[count].port
            );
    }
}
else
{
    n2++;
    fprintf(errorFile, "%d %d %d %d",
        (i + 1),
        array[count].src,
        array[count].dest,
        array[count].type,
        array[count].port
        );
}
fclose(errorFile);
fclose(outFile);
return 0;
}

这里面有很多常见的错误。你在读哪本书?

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

原谅我。我冒昧地清理了你的一些代码并浓缩了一些逻辑。

不应强制转换mallocrealloc的返回值

当我讨论类型的话题时,您的编译器不是在警告您&array[count].data的类型与对应于%s的类型不兼容吗?不要强制转换。只需移除&,并识别表示数组的表达式array[count].data是如何转换为适当类型的指针的。

x = realloc(x, ...);,其中x是(几乎)总是不正确的任何表达式。您需要使用一个临时变量,以便在不泄漏内存的情况下正确处理错误(以下示例)。。。当我讨论realloc的用法时,第一个参数可以是NULL,在这种情况下,realloc的行为将类似于malloc,所以从技术上讲,第一个malloc是不必要的膨胀。。。

struct record *array = NULL;
void *temp = realloc(array, (count + 1) * sizeof *array);
if (!temp) {
    puts("ERROR ALLOCATING MEMORY!");
    exit(EXIT_FAILURE);
}
array = temp;

您考虑过fgetsfscanf("%s", ...)之间的区别吗你知道前者是用来读的,而后者是用来读词吗?这可以解释你的问题;fscanf在看到空间时会停止,留下空间之后的所有内容供下一个fscanf调用处理。结果如何?fscanf的无限循环失败。

您是否考虑过并非所有fscanf失败都返回EOF如果您要求fscanf读取一个int(使用%d),并且它立即遇到非十进制数字,则无法继续;发生转换失败

如果要确保fscanf成功读取所有5个字段,则需要将返回值与5进行比较,而不是与EOF进行比较

我想你很可能是想读四个冒号分隔的ints之后的行的剩余部分,下面是我天真地做到这一点的方法:

array = NULL;
struct record record;
while (fscanf(inFile, "%d:%d:%d:%d:%99[^n]", &record.src,  &record.dest
                                            , &record.type, &record.port
                                            ,  record.data) == 5) {
    /* It's possible that a user might enter more than   *
     * 99 chars for the last field, so when that happens *
     * we should discard the remainder...                */
    if (getchar() != 'n') {
        puts("WARNING: Maximum field length for data is 99; user input truncated");
        fscanf(inFile, "%*[^n]");
    }
    void *temp = realloc(array, (count + 1) * sizeof *array);
    if (!temp) {
        puts("ERROR ALLOCATING MEMORY!");
        exit(EXIT_FAILURE);
    }
    array = temp;
    array[count++] = record;
}

最新更新