2017-02-01 4 views
1

Ich bin völlig neu in C-Programmierung vor kurzem begann ich ein bisschen mehr in Zeiger und ich habe ein Problem mit meinem Code aufgetreten.Struct und Char **

Also ich versuche, eine Zeichenfolge an eine char** übergeben, die in eine Struktur ist, aber ich bekomme immer Fehler. Vielen Dank im Voraus hier ist ein Code

Dies ist die Struktur, die ich verwendet habe.

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

Und das ist es, was ich versuche, hineinzulegen. Innerhalb der ersten, wenn Sie sehen können, versuche ich strcpy, aber scheitert. Auch wenn ich & oder * setze.

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

Bitte nicht über 'feof()' - http://stackoverflow.com/questions/5431941/why-is-which-feof-file-always-wrong –

+5

Zeigen Sie uns, wo Sie 'QBoat-> initialisieren car_id' –

+1

Veröffentlichen Sie Ihr gesamtes Programm. –

Antwort

3

Es ist sehr einfach zu vermasseln Speicherzuweisung und Aufhebung der Zuordnung mit einer Struktur. Daher ist es am besten, immer neue Funktionen zu schreiben und Funktionen für jede Struktur zu zerstören.

/* 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); 
} 

Nun, da die Struktur zugeordnet wurde, und die Liste der Artikel, müssen Sie darauf achten, nicht hinzuzufügen, zu viele Elemente. Ihr Code, der zur Warteschlange hinzugefügt wird, überprüft nie, ob die Kapazität der Warteschlange überschritten ist. Aus diesem Grund empfiehlt es sich, eine Funktion zum Hinzufügen von Elementen zu schreiben, die die Kapazität korrekt überprüfen.

Die Warteschlange Logik kann falsch sein, ich bin nicht gut mit Warteschlangen, aber Sie bekommen die Idee. Sie könnten die Warteschlange später sogar erweitern, um die Größe automatisch zu ändern.

Jetzt können Sie diese Arbeit isoliert testen. Sobald Sie sicher sind, dass sie funktionieren, können Sie versuchen, aus einer Datei zu lesen und Ihre Warteschlangenfunktionen zu verwenden.

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

Die meiste Arbeit bestimmt jetzt, welche Warteschlange zu verwenden ist.

+1

Mit Code wie 'queue-> items = malloc (Kapazität * sizeof (char *));', finde ich 'queue-> items = malloc (Kapazität * sizeof * (queue-> items)) '' einfacher zu codieren, zu überprüfen und zu pflegen. – chux