2017-02-01 3 views
1

Я недавно был новичком в программировании на языке C. Я начал искать немного больше в указателе, и я столкнулся с проблемой с моим кодом.Struct and char **

Так что я пытаюсь передать строку в char**, который находится в структуре, но я всегда получаю ошибки. Спасибо заранее, вот какой-то код

Это структура, которую я использовал.

typedef struct Queue { 
int capacity; 
int front; 
int rear; 
int size; 
char **car_id; 
}; 

И вот что я пытаюсь вложить в него. Внутри первого, если вы видите, я пытаюсь сделать strcpy, но не получается. Даже если я ставлю & или *.

printf("Printing the contect of the TXT file\n"); 
int countS=-1,countQ=-1; 
char line[10]; 
FILE *fp; 
fp = fopen("car.txt","r"); 
if (fp == NULL) { 
    printf("Error: File doesn't exist exiting the programm!"); 
    exit(1); 
} 
while(!feof(fp)){ 
     fgets(line,10,fp); 
     printf("%s",line); 

     if(line[(strlen(line))-2]=='Q'){ 
     countQ++; 
     line[strlen(line)-2] = 0; 
     strcpy(car_id,line); 
     strcpy(QBoat->car_id[countQ],car_id); 
     QBoat->rear=countQ; 
     QBoat->front=0; 
     QBoat->size=countQ; 
     }else if(line[(strlen(line))-2]=='S'){ 
     countS++; 
     line[strlen(line)-2] = 0; 
     SBoat->top = countS; 
     //strcpy(SBoat->car_id[countS],line); 
     } 

} 
fclose(fp); 
+3

Пожалуйста, не перегибайте 'feof()' - http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong –

+5

Покажите нам, где вы инициализируете 'QBoat-> car_id' –

+1

Отправьте всю вашу программу. –

ответ

3

Очень легко испортить выделение и освобождение памяти с помощью структуры. Поэтому лучше всегда писать новые и уничтожать функции для каждой структуры.

/* To avoid confusion, it's best to declare structs as type definitions 
    and name them Something_t. Capital letter to avoid conflict with 
    built in types, _t to note that it is a type, and to avoid conflict 
    with other names. */ 
typedef struct { 
    /* Using size_t means less type casting */ 
    size_t capacity; 
    int front; 
    int rear; 
    int size; 
    char **items; 
} Queue_t; 

Queue_t *Queue_new(const size_t capacity) { 
    /* Use calloc because we have to zero everything anyway */ 
    Queue_t *queue = calloc(1, sizeof(Queue_t)); 

    /* Allocate enough space to store a list of whatever 
     queue->items is a list of */ 
    queue->capacity = capacity; 
    queue->items = malloc(capacity * sizeof(*(queue->items))); 

    return queue; 
} 

void Queue_destroy(Queue_t *queue) { 
    /* Since items were copied into the list, it's the queue's responsibility 
     to free them */ 
    for(int i = queue->front; i < queue->rear; i++) { 
     free(queue->items[i]); 
    } 

    /* Now free the list of items */ 
    free(queue->items); 

    /* And finally the struct itself */ 
    free(queue); 
} 

Теперь, когда структура была выделена, и его список элементов, вы должны убедиться, чтобы не добавить слишком много элементов. Ваш код, добавляющий в очередь, никогда не проверяет, переполняет ли он объем очереди. По этой причине лучше написать функцию для добавления элементов, которые будут правильно проверять емкость.

void Queue_add(Queue_t *queue, const char *item) { 
    if(queue->size >= (int)queue->capacity) { 
     fprintf(stderr, "Queue capacity of %zu exceeded!\n", queue->capacity); 
     exit(1); 
    } 

    /* You used strcpy in your example, so I'm following that. 
     You could also not copy and store the original pointer. */ 
    queue->items[ queue->rear ] = strdup(item); 

    /* I don't know if this is right */ 
    queue->rear++; 
    queue->size++; 
} 

Логика очередей может быть неправильной, я не очень хорош в очередях, но вы получаете идею. Вы можете даже позже расширить очередь, чтобы автоматически изменить размер.

Теперь вы можете протестировать эти работы изолированно. Как только вы уверены, что они работают, вы можете попробовать прочитать из файла и использовать функции очереди.

int main() { 
    char filename[] = "car.txt"; 
    FILE *fp = fopen(filename,"r"); 
    if (fp == NULL) { 
     fprintf(stderr, "Couldn't read '%s': %s\n", filename, strerror(errno)); 
     exit(1); 
    } 

    /* Just picked a number out of thin air */ 
    Queue_t *qboats = Queue_new(256); 
    Queue_t *sboats = Queue_new(256); 

    char line[10]; 
    while(fgets(line, 10, fp) != NULL) { 
     size_t len = strlen(line); 

     /* Choose the right queue to use */ 
     Queue_t *queue; 
     switch (line[len-2]) { 
      case 'S': 
       queue = sboats; 
       break; 
      case 'Q': 
       queue = qboats; 
       break; 
      default: 
       fprintf(stderr, "Can't understand line '%s'\n", line); 
       continue; 
       break; 
     } 

     /* Chop off the identifier */ 
     line[len - 2] = '\0'; 

     /* Add to the queue */ 
     Queue_add(queue, line); 
    } 

    /* Do something with the queues. This should probably be Queue_print(). */ 
    for(int i = qboats->front; i < qboats->rear; i++) { 
     printf("qboat: %s\n", qboats->items[i]); 
    } 

    for(int i = sboats->front; i < sboats->rear; i++) { 
     printf("sboat: %s\n", sboats->items[i]); 
    } 

    /* Now clean them up */ 
    Queue_destroy(sboats); 
    Queue_destroy(qboats); 
} 

Большая часть работы теперь определяет, какую очередь использовать.

+1

С кодом типа 'queue-> items = malloc (capacity * sizeof (char *));', я нахожу 'queue-> items = malloc (capacity * sizeof * (queue-> items)); 'проще кодировать, просматривать и поддерживать. – chux

 Смежные вопросы

  • Нет связанных вопросов^_^