我的课要求我用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循环会一直持续下去?
答案 0 :(得分:0)
欢迎来到SO!请注意,确实需要 MCVE来解决此类问题...此外,不更新您的问题以更改代码;这会更改问题,这会使之前的所有答案都无效。如果您要提出新问题,请将其作为一个新问题!
char *tempLine = malloc(sizeof tempLine); // Suggested to me as a fix
我不相信这个修复。为什么要分配一个指向char
的内存块,其大小为char *
?多么不寻常......你的代码中有几个其他变量像这样初始化,看起来像猜测。你的猜测可能会导致问题。
tempLine = fgets(buffer, 255, cfgfile);
用buffer
或NULL
覆盖指向该分配的指针,这会导致内存泄漏。谁建议修复你需要了解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也将最终泄露。