2013-09-18 3 views
0

У меня есть функция, которая пытается прочитать каждую строку файла, а затем использовать sscanf для передачи значений в массив структур, создавая новую структуру для каждой строки файла, которая не является строка комментария, содержащая символ '#'. Это мой код:Пока петля застряла в ожидании ввода

typedef struct { 
    int row, col, C, D; 
    char program[80]; 
} agentDetails; 

Мои структуры определены в файле заголовка, # включены в основной файл.

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 ...), а затем ждет ввода.

Я знаю, что этот код работает, если я пытаюсь преобразовать значения в переменные, инициализированные внутри функции, это только кажется ошибкой, когда я использую массив структур. Что здесь происходит?


Я изменил код, чтобы он работает, смотрите ниже:

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++; 
    } 
} 

я не использую таНос, однако. Это проблема? Это вызовет проблемы?

+0

как 'currentLine' объявлен? – phoxis

+0

char currentLine [80]; – user2790954

+0

Не должно быть запятой между агентами '& agents [n] .C [n] .program' в' sscanf'? – phoxis

ответ

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++; 
    } 
} 

для каждого цикла вы создаете массив agentDetails размера п, то п увеличивается, и новый массив создается. Вы также используете n в своих аргументах для sscanf, потенциально выходящих за пределы массива. Я думаю, что будет что-то подобное будет больше соответствовать, что вы хотите:

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.

0

Насколько я могу сказать от кода, при условии ... В этой строке:

agentDetails agents[n]; /*create new struct in array agents*/ 

создать н-размерный массив структур agentDetails.
В sscanf вы пытаетесь записать некоторые детали в агенты структуры [n], которых нет в массиве, так как размер массива равен 0- (n-1). Если я ошибаюсь, расскажите подробнее о своем коде.

Вы пытаетесь объявить массив неизвестного размера, но это не работает.
Вы можете перебирать файл по одному, подсчитывая количество агентов в файле, а затем выделять с помощью malloc столько памяти, сколько вам нужно. Или вы можете malloc и realloc на каждой итерации (что может быть плохой идеей).

1-й. Удалить объявление массива из цикла.
2-й. Прочитайте, как работает malloc.
3-й. Вы сможете исправить код самостоятельно после этих шагов.

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++; 

Вы создаете массив внутри цикла While (ошибка 1) размера n (предполагается, что 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++; 
    } 
} 
0

Это неправильно по нескольким пунктам.

  1. Вы заявляете и выделить char** agents, затем тень его agentDetails agents[n]
  2. Вы читаете мимо конца agents массива. Допустимые индексы от 0 до (n-1).
  3. Неправильные технические характеристики вашего формата.

вопросы НКУ эти предупреждения:

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] 
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; 
} 

файл test.txt

32 10 a megharaj india 

выход

currentline = 32 10 a megharaj india 
Смежные вопросы