循环卡住等待输入

时间:2013-09-18 10:09:08

标签: c loops while-loop

我有一个函数试图读取文件的每一行,然后使用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。这是一个问题吗?这会引起问题吗?

5 个答案:

答案 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)

这在几个方面都是错误的。

  1. 您声明并分配char** agents,然后用agentDetails agents[n]
  2. 隐藏它
  3. 您正在阅读agents数组的末尾。有效索引为0到(n-1)。
  4. 您的格式规范错误。
  5. 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