尝试在C中逐行读取文件,但while循环永远不会终止

时间:2017-02-09 01:37:49

标签: c

我的课要求我用C编写操作系统模拟器。第一个项目是读取两个文件,一个配置文件和一个元数据文件。我第一次尝试运行完成的代码导致了分段错误(我相信我已经解决了)。现在我的fgets语句逐行阅读有问题。它读取每一行,但它永远不会停止读取行。它无限期地读取文件直到我结束该过程。我在while循环中放了一个printf语句,这样我就可以看到它的读取内容了,它确实遍历每一行。

int readCfgFile (char *filename, CONFIG *filedata)
{
    char buffer[255], trash[255];
    FILE *cfgfile = malloc(sizeof cfgfile);
    cfgfile = fopen(filename, "r"); // Assumed where segfault was
    if(!cfgfile)
    {
        return -2; // Error opening file
    }
    char *schedulingCode = malloc(8);
    char *logToCode = malloc(200);
    char *tempLine; // Suggested to me as a fix (the using a separate variable part)
    fgets(trash, 255, cfgfile); //Trash the first line of the file
    tempLine = fgets(buffer, 255, cfgfile);
    while(tempLine != NULL)
    {
        sscanf(buffer, "Version/Phase: %d", &filedata->version);
        sscanf(buffer, "File Path: %s", filedata->metaPath);
        sscanf(buffer, "CPU Scheduling Code: %s", schedulingCode);
        sscanf(buffer, "Quantum Time (cycles): %d", &filedata->quantum);
        sscanf(buffer, "Memory Available (KB): %d", &filedata->memory);
        sscanf(buffer, "Processor Cycle Time (msec): %d", &filedata->processTime);
        sscanf(buffer, "I/O Cycle Time (msec): %d", &filedata->ioTime);
        sscanf(buffer, "Log To: %s", logToCode);
        sscanf(buffer, "Log File Path: %s", filedata->logPath);
        tempLine = fgets(buffer, 255, cfgfile);
        if(tempLine == NULL)
        {
            break;
        }
        printf("%s\n", buffer);
    }

该文件如下所示:

Start Simulator Configuration File
Version/Phase: 1.0
File Path: Test_3.mdf
CPU Scheduling Code: NONE
Quantum Time (cycles): 55
Memory Available (KB): 667
Processor Cycle Time (msec): 10
I/O Cycle Time (msec): 20
Log To: Monitor
Log File Path: logfile_1.lgf
End Simulator Configuration File.

有没有人知道为什么while循环会一直持续下去?

2 个答案:

答案 0 :(得分:0)

欢迎来到SO!请注意,确实需要 MCVE来解决此类问题...此外,更新您的问题以更改代码;这会更改问题,这会使之前的所有答案都无效。如果您要提出新问题,请将其作为一个新问题!

char *tempLine = malloc(sizeof tempLine); // Suggested to me as a fix

我不相信这个修复。为什么要分配一个指向char的内存块,其大小为char *?多么不寻常......你的代码中有几个其他变量像这样初始化,看起来像猜测。你的猜测可能会导致问题。

然后

tempLine = fgets(buffer, 255, cfgfile);bufferNULL覆盖指向该分配的指针,这会导致内存泄漏。谁建议修复你需要了解valgrind(就像你一样)。

尽管如此,如果您希望垃圾输入一行,那么如果没有像这样的中间缓冲区,那就更好了:

fscanf(cfgfile, "%*[^\n]");
fgetc(cfgfile);

我很好奇,为什么你似乎使用%d来读取浮点数据呢?

sscanf(buffer, "Version/Phase: %d", ... // Version/Phase: 1.0

如果我只能看到filedata->version的类型,我可以将此验证为错误...

您声称已更新此代码,但我看不到更新:

tempLine = fgets(buffer, 255, cfgfile);
if(buffer == NULL) // Even checking to see if buffer was null doesn't work

这里有一个错误,为了识别它,我希望您在此测试用例中向我展示fgets如何像您期望的那样分配buffer = NULL;

#include <stdio.h>
char *fgets_fake(char *b, int b_length, FILE *f) {
    /* INSERT CODE HERE! */
    /* Show me how `fgets` can assign `buffer = NULL;` here */
    return b;
}
int main(void) {
    char *buffer = "HELLO WORLD!";
    fgets_fake(buffer, 0, 0);
    printf("Is buffer NULL? %s\n", b ? "no" : "yes");
}

您可能需要if (tempLine == NULL),因为可以重新分配(返回后)。

答案 1 :(得分:0)

当你说循环永远运行时,你会在循环终止之前为语句 printf(&#34;%s \ n&#34;,缓冲区); 继续获取一些输出。那是什么打印?

我建议独立于sscanf代码测试循环逻辑。下面的块应该这样工作(不需要额外的检查等)。

fgets(buffer, 255, cfgfile);  // just to skip the first line
while( (tempLine = fgets(buffer, 255, cfgfile)) != NULL)
{
      // all the scanfs to read from tempLine/buffer
      ..
}

有了这个,你可能想要添加你的sscanfs并逐步从那里开始。围绕 FILE * cfgfile = malloc(sizeof cfgfile); 的一些小评论。这不是必需的,因为对fopen的调用将返回指向FILE的指针,并且您最终会泄漏malloc&lt; cfg文件。也不确定这是否是完整的代码,但logToCode和schedulingCode也将最终泄露。