我有一个函数试图读取文件的每一行,然后使用sscanf将值传递给结构数组,为文件的每一行创建一个新的结构,而不是包含char'#'的注释行 . 这是我的代码:
typedef struct {
int row, col, C, D;
char program[80];
} agentDetails;
我的结构在头文件中定义,#included在主文件中 .
char currentLine[80];
char** agents;
int n=0;
agents = malloc(sizeof(char*)*4);
while (fgets(currentLine, sizeof currentLine, file) != NULL) {
if(!strchr(currentLine, '#')) {
agentDetails agents[n]; /*create new struct in array agents*/
sscanf(currentLine, "%d %d %c %s %s", &agents[n].row, &agents[n].col, &agents[n].C, agents[n].program, agents[n].D);
n++;
}
}
这是有效的,但是当它到达文件末尾时它不会退出循环,它就在那里等待输入 . 我已经尝试逐步使用gdb,在最后一行之后它步入while(fgets ...)行,然后等待输入 .
我知道这个代码有效,如果我尝试将sscanf值转换为函数内初始化的变量,当我使用结构数组时,它似乎只是出错 . 这里发生了什么?
我已经更改了代码,所以它可以工作,见下文:
int n = 0;
int i = 0;
while (fgets(currentLine, sizeof currentLine, file) != NULL) {
if(!strchr(currentLine, '#')) {
n++;
}
}
rewind(file);
agentDetails agents[n];
while (fgets(currentLine, sizeof currentLine, file) != NULL) {
if(!strchr(currentLine, '#')) {
sscanf("same as above");
i++;
}
}
但是,我不使用malloc . 这是一个问题吗?这会引起问题吗?
5 回答
你的代码看起来有点奇怪
对于每个循环,您创建一个大小为n的agentDetails数组,然后递增n并创建一个新数组 . 您还可以在sscanf的参数中使用n来潜在地超出数组 . 我认为这样的事情会更符合你的想法:
检查返回值也是一种很好的做法,例如什么sscanf返回以查看预期参数的数量是否与sscanf找到的相同 .
仔细看看这个:
您正在大小
n
的while循环(错误1)内创建一个数组(假设n
具有非零值) . 然后,您将sscanf
进入数组索引n
,它始终传递数组的限制(错误2) . 在循环结束时,抛出数组,因为它的范围结束(错误3) .你的代码应该是这样的:
这有几点是错误的 .
你声明并分配
char** agents
,然后用agentDetails agents[n]
遮住它您正在读取
agents
数组的末尾 . 有效索引为0到(n-1) .您的格式规格错误 .
GCC发布以下警告:
据我所知,你提供的代码......在这一行:
你创建n大小的结构数组agentDetails .
在sscanf中,您尝试将一些细节写入结构代理[n],这不在数组中,因为数组大小为0-(n-1) . 如果我错了,请提供有关代码的更多详细信息 .
你尝试声明一个未知大小的数组,但它不会那样工作 .
您可以迭代文件一次,计算文件中有多少个代理,然后根据需要使用malloc分配内存 . 或者你可以在每次迭代中使用malloc和realloc(这可能是个坏主意) .
1st. 从循环中删除数组声明 .
2nd. 做一些关于malloc如何工作的阅读 .
3rd. 您可以轻松地在这些步骤后自行修复代码 .
只是展示你的部分代码 . 这工作得很好 .
file test.txt
产量