我有一个函数试图读取文件的每一行,然后使用sscanf将值传递给结构数组,为文件的每一行创建一个新的结构,而不是包含char的注释行'# ”。这是我的代码:
typedef struct {
int row, col, C, D;
char program[80];
} agentDetails;
我的结构是在头文件中定义的,#include包含在主文件中。
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。这是一个问题吗?这会引起问题吗?
答案 0 :(得分:0)
你的代码看起来有点奇怪
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++;
}
}
对于每个循环,您创建一个大小为n的agentDetails数组,然后递增n并创建一个新数组。您还可以在sscanf的参数中使用n来潜在地超出数组。 我认为这样的事情会更符合你的想法:
int i = 0; // assuming n is defined somewhere else
agentDetails agents[n]; /*create new struct in array agents*/
while (fgets(currentLine, sizeof currentLine, file) != NULL && i < n)
{
if(!strchr(currentLine, '#'))
{
sscanf(currentLine, "%d %d %c %s %s", &agents[i].row, &agents[i].col, &agents[i].C, agents[i].program, agents[i].D);
i++;
}
}
检查返回值也是一种很好的做法,例如什么sscanf返回以查看预期参数的数量是否与sscanf找到的相同。
答案 1 :(得分:0)
据我所知,你提供的代码...... 在这一行:
agentDetails agents[n]; /*create new struct in array agents*/
你创建n大小的结构数组agentDetails
在sscanf中,您尝试将一些细节写入结构代理[n],这不在数组中,因为数组大小为0-(n-1)。如果我错了,请提供有关您的代码的更多详细信息
你尝试声明一个未知大小的数组,但它不会那样工作。
您可以迭代文件一次,计算文件中有多少代理,然后根据需要使用malloc分配内存。或者你可以在每次迭代中使用malloc和realloc(这可能是个坏主意)。
1st。从循环中删除数组声明 第二。。阅读一下malloc的工作原理 第三。您可以轻松地在这些步骤后自行修复代码。
答案 2 :(得分:0)
仔细看看:
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++;
您正在大小为n
的while循环(错误1)中创建一个数组(假设n
具有非零值)。然后你sscanf
进入索引n
的数组,它总是传递数组的限制(错误2)。在循环结束时,抛出数组,因为它的范围结束(错误3)。
您的代码应该是这样的:
agentDetails agents[n]; /* make sure to get the correct `n` from somewhere, for example the file itself */
/* better yet, use `malloc`, since `n` could be really large */
i = 0;
while (fgets(currentLine, sizeof currentLine, file) != NULL) {
if(!strchr(currentLine, '#')) {
sscanf(currentLine, "%d %d %c %s %s", &agents[i].row, &agents[i].col, &agents[i].C, agents[i].program, agents[i].D);
i++;
}
}
答案 3 :(得分:0)
这在几个方面都是错误的。
char** agents
,然后用agentDetails agents[n]
agents
数组的末尾。有效索引为0到(n-1)。GCC发布了这些警告:
warning: format ‘%c’ expects argument of type ‘char *’,
but argument 5 has type ‘int *’ [-Wformat]
warning: format ‘%s’ expects argument of type ‘char *’,
but argument 7 has type ‘int’ [-Wformat]
答案 4 :(得分:0)
只是展示你的代码部分。这是有效的。
#include<stdio.h>
int main()
{
FILE *file;
int agent1, agent2;
char c, s1[10],s2[10],currentline[100];
char currentLine [100];
file = fopen ("test.txt" , "r");
while (fgets(currentline, 100, file) != NULL) {
printf("currentline = %s\n", currentline);
fflush(stdout);
sscanf(currentLine, "%d %d %c %s %s", &agent1, &agent1, &c, s1, s2);
}
fclose(file);
return 0;
}
file test.txt
32 10 a megharaj india
输出
currentline = 32 10 a megharaj india