2016-03-21 7 views
0

Also lese ich Daten aus einer Datei getrennt durch Kommas. Aus irgendeinem Grund durchläuft der Code nicht die gesamte Datei und druckt nur einen bestimmten Komponententyp aus.Einlesen von einer Datei mit Adresse anstelle von Werten

Auch für die NumOfItems und Preis, ich bekomme nur die Adresse ausgedruckt werden, anstatt die Werte!

Hier ist mein Code:

typedef struct inventory { 
    char *componentType; 
    char *stockCode; 
    int numOfItems; 
    int price; 
} inventory; 


int main(int argc, char** argv) 
{ 

    char str[255]; 
    FILE *invf= fopen("inventory.txt", "r"); 
    // creating an array of structs 
    struct inventory inv[384]; 
    // counter for array position 
    int counter = 0; 
    while (fgets(str, 256, invf) != NULL){ 
     char *componentType = strtok(str, " ,"); 
     // the NULL means it will pick up where it left off 
     char *stockCode = strtok(NULL, " ,"); 
     int *numOfItems = strtok(NULL, " ,"); 
     int *price = strtok(NULL, " ,"); 

     // adding to the struct 
     inv[counter].componentType = componentType; 
     inv[counter].stockCode = stockCode; 
     inv[counter].numOfItems = &numOfItems; 
     inv[counter].price = &price; 
     counter++; 
    } 
    int i = 0; 
    for(i =0; i <300; i++){ 
     printf("%s %s %d %d \n", inv[i].componentType, inv[i].stockCode, inv[i].numOfItems, inv[i].price); 
    } 

    return EXIT_SUCCESS; 
} 

CSV Beispiel

lightbulb, RES_16M, 711, 1, 16M 
    lightbulb, RES_16Ms, 7112, 1, 16Mk 
    card, CAP_2700pf, 75, 26, 2700pf 
    card, CAP_2700pfs, 75, 262, 2700pff 
    Current, ASDba, 0, 800, "doesn't follow trend" 
    Current, TL741, 20, 12, "doesn't either" 
+3

Sie könnten 'strdup()' s der Zeiger 'strtok()' zurückgeben, anstatt diese Zeiger in Ihren Strukturen direkt zu speichern, da 'fgets()' den Inhalt überschreiben wird. – EOF

+1

Sie müssen "atoi" oder etwas ähnliches, um ein int von einer Zeichenfolge zu erhalten. – crashmstr

+0

Was versuchen Sie mit 'int * numOfItems = strtok (NULL,", ");'? Wenn Ihr Compiler Sie nicht dafür anschreien wird, bedeutet das, dass es nicht richtig konfiguriert ist. – Medinoc

Antwort

0

Ihr componenType ein Zeiger auf Zeichen ist. Jedes Mal, wenn Sie eine Zeile lesen, weisen Sie den Zeiger der Zeile componentType zu. Am Ende zeigen alle Inventarelemente auf denselben Ort, der der letzte gelesene Wert ist. Sie müssen Speicher dafür unter Verwendung von malloc zuweisen und dann den Wert kopieren.

In der gleichen Weise machen Sie Integer-Elemente eine Zeiger auf eine (String) Variable. Aber Sie müssen den Wert erhalten. Verwenden Sie atoi().

Hinweis weiter, dass char str[255]; kann 255 Zeichen enthalten, aber Sie bitten fgets, maximal 256 Zeichen zu lesen. Sie vergessen, das abschließende Nullzeichen zuzuweisen.

Vergessen Sie nicht, das counter < 384 zu überprüfen.


EDIT (hinzugefügt Führung)

Sie bauen ein Array mit Inventargegenstände. Sie können derzeit nicht mehr als 384 Elemente, die Größe des Arrays, lesen. Wenn die Anzahl der Elemente "beliebig" sein kann, benötigen Sie eine dynamischere Datenstruktur. Fürs Erste ist das Array ausreichend, aber Sie müssen sicherstellen, dass die Grenzen beim Lesen einer Inventardatei nicht überschritten werden.

Jedes Mal, wenn Sie eine Zeile lesen, brechen Sie diese Zeile von links nach rechts in Informationselemente. Für Elemente, die vom Typ String sind, müssen Sie Speicher zuweisen die Zeichenfolge Daten zu halten:

inv[counter].componentType = malloc(strlen(componentType)+1); 
    strcpy(inv[counter].componentType, componentType); 

Wenn numerische Informationen zu lesen, es ist immer noch als String und Sie müssen, dass in eine ganze Zahl konvertieren:

int numOfItems = atoi(strtok(NULL, " ,")); 

oder:

inv[counter].numOfItems = atoi(strtok(NULL, " ,")); 

Nachdem das Array auf diese Weise bauen Sie es in Ihrem Programm verwenden können. Um eine Komponente Typ zu ändern, zum Beispiel:

free(inv[counter].componentType);        // release old memory 
    inv[counter].componentType = malloc(strlen(newComponentType)+1); // get new 
    strcpy(inv[counter].componentType, newComponentType); 

Sobald Sie fertig sind, sollten Sie den gesamten Speicher freigeben zugewiesen mit malloc durch free Aufruf für jedes Element.

+0

Vielen Dank für den Versuch, es für mich zu klären, immer noch ein wenig zu kämpfen .. nur begann diese Woche C zu lernen, so dass jedes Bit der Daten dynamisch Speicher zugeordnet werden muss? –

+0

User36etc, habe ich einige Informationen hinzugefügt. –

+0

Funktioniert perfekt danke, warum ist es nicht notwendig, die int-Werte zu kopieren? –

Verwandte Themen