2016-03-18 12 views
-2

Ich überarbeite Zeiger in C und erstelle einige Übungsübungen für mich. Ich dachte, es wäre gut, in einigen Strukturen über ein Array von struct-Pointern zu lesen, dann das Array anzuzeigen und zu sortieren. Das Problem, das ich habe, ist, denke ich, ziemlich einfach. Der folgende Code liest den ersten Eintrag, die firstName-Zeichenfolge ist jedoch immer null. Nach dem Drucken der ersten Struktur und Fortsetzen der zweiten wird es zu dem Zeitpunkt "Boom", um in die firstName-Zeichenfolge zu lesen. Ich dachte, ich habe die char-Zeichenfolgen in initParty() korrekt initialisiert, also bin ich mir nicht sicher, was das Problem hier ist. Irgendwelche Ideen?Auffüllen der Schnur in einem Feld Zeiger auf Strukturen

Probelauf:

* (GDB) laufen Startprogramm:/home/remnux/C/struct der Vorname eingeben: john den Nachnamen eingeben: smith Geben Sie die SSN: 1234 (null) smith, 1234

Programm empfangenes Signal SIGSEGV, Segmentierungsfehler. 0x00000000004009a4 in getParty (p = 0x0) bei struct.c: 51 51 scanf ("% s", p-> firstName); (GDB) *

#include <stdio.h> 
#include <stdbool.h> 
#include <stdlib.h> 

struct person{ 
    char *firstName; 
    char *lastName; 
    int ssn; 
    }; 

void print(struct person* p){ 
    printf("\n%s ", p->firstName); 
    printf("%s, ", p->lastName); 
    printf("%d\n ", p->ssn); 
} 

bool isGreaterThan(struct person *p1, struct person *p2){ 
    return (strcmp(p1->firstName > p2->firstName) > 0) 
    || ((strcmp(p1->firstName > p2->firstName) == 0) && (strcmp(p1->lastName > p2->lastName) > 0)) 
    || ((strcmp(p1->firstName > p2->firstName) == 0) && (strcmp(p1->lastName > p2->lastName) == 0)) && (p1->ssn - p2->ssn > 0); 
} 

void printArray(struct person** parray, int size){ 
    int i; 
    for(i = 0; i < size; i++) 
    printf("%s %s, %d", parray[i]->firstName, parray[i]->lastName, parray[i]->ssn); 
} 

void sort(struct person** parray, int size){ 
    int i, j; 
    for(i = 0; i < size; i++) 
    for(j = 0; j < size-1; j++){ 
     if(isGreaterThan(parray[j], parray[j+1])){ 
     struct person *temp = parray[j]; 
     parray[j] = parray[j+1]; 
     parray[j+1] = temp; 
     } 
    }  
return; 
} 

void initParty(struct person *p){ 
    p = (struct person*)malloc(sizeof(struct person)); 
    p->firstName = (char*)malloc(100 * sizeof(char)); 
    p->lastName = (char*)malloc(100 * sizeof(char)); 
} 

void getParty(struct person *p){ 
    int ch; 
    printf("\nEnter the firstname: "); 
    scanf("%s", p->firstName); 
    while((ch = getchar()) != '\n' && ch != EOF); 
    printf("\nEnter the lastname: "); 
    scanf("%s", p->lastName); 
    while((ch = getchar()) != '\n' && ch != EOF); 
    printf("\nEnter the ssn: "); 
    scanf("%d", &(p->ssn)); 
    while((ch = getchar()) != '\n' && ch != EOF); 
} 

int main(){ 
    int i, ch, size = 2; 
// printf("Input the number of people you wish to enter: "); 
// scanf("%d", &size); 
// while((ch = getchar()) != '\n' && ch != EOF); 
    struct person *parray[size]; 
    for(i = 0; i < size; i++){ 
    initParty(parray[i]); 
    getParty(parray[i]); 
    print(parray[i]); 
    } 
    sort(parray, size); 
    printArray(parray, size); 
} 

bearbeiten, nachdem die Warnungen zu beseitigen, wenn sie mit -Wall Kompilieren:

#include <stdio.h> 
#include <stdbool.h> 
#include <stdlib.h> 
#include <string.h> 

struct person{ 
    char *firstName; 
    char *lastName; 
    int ssn; 
    }; 

void print(struct person* p){ 
    printf("\n%s ", p->firstName); 
    printf("%s, ", p->lastName); 
    printf("%d\n ", p->ssn); 
} 

/*bool isGreaterThan(struct person *p1, struct person *p2){ 
    return ((strcmp(p1->firstName > p2->firstName) > 0) 
    || ((strcmp(p1->firstName > p2->firstName) == 0) && (strcmp(p1->lastName > p2->lastName) > 0)) 
    || ((strcmp(p1->firstName > p2->firstName) == 0) && (strcmp(p1->lastName > p2->lastName) == 0) && (p1->ssn - p2->ssn > 0))); 
}*/ 

void printArray(struct person** parray, int size){ 
    int i; 
    for(i = 0; i < size; i++) 
    printf("%s %s, %d", parray[i]->firstName, parray[i]->lastName, parray[i]->ssn); 
} 

/*void sort(struct person** parray, int size){ 
    int i, j; 
    for(i = 0; i < size; i++) 
    for(j = 0; j < size-1; j++){ 
     if(isGreaterThan(parray[j], parray[j+1])){ 
     struct person *temp = parray[j]; 
     parray[j] = parray[j+1]; 
     parray[j+1] = temp; 
     } 
}  
    return; 
} */ 

void initParty(struct person *p){ 
    p = (struct person*)malloc(sizeof(struct person)); 
    p->firstName = (char*)malloc(100 * sizeof(char)); 
    p->lastName = (char*)malloc(100 * sizeof(char)); 
} 

void getParty(struct person *p){ 
    int ch; 
    printf("\nEnter the firstname: "); 
    scanf("%s", p->firstName); 
    while((ch = getchar()) != '\n' && ch != EOF); 
    printf("\nEnter the lastname: "); 
    scanf("%s", p->lastName); 
    while((ch = getchar()) != '\n' && ch != EOF); 
    printf("\nEnter the ssn: "); 
    scanf("%d", &(p->ssn)); 
    while((ch = getchar()) != '\n' && ch != EOF); 
} 

int main(){ 
    int i, size = 2; 
// printf("Input the number of people you wish to enter: "); 
// scanf("%d", &size); 
// while((ch = getchar()) != '\n' && ch != EOF); 
    struct person *parray[size]; 
    for(i = 0; i < size; i++){ 
    initParty(parray[i]); 
    getParty(parray[i]); 
    print(parray[i]); 
    } 
    //sort(parray, size); 
    printArray(parray, size); 
    return 0; 
}  
    return; 
} */ 

void initParty(struct person *p){ 
    p = (struct person*)malloc(sizeof(struct person)); 
    p->firstName = (char*)malloc(100 * sizeof(char)); 
    p->lastName = (char*)malloc(100 * sizeof(char)); 
} 

void getParty(struct person *p){ 
    int ch; 
    printf("\nEnter the firstname: "); 
    scanf("%s", p->firstName); 
    while((ch = getchar()) != '\n' && ch != EOF); 
    printf("\nEnter the lastname: "); 
    scanf("%s", p->lastName); 
    while((ch = getchar()) != '\n' && ch != EOF); 
    printf("\nEnter the ssn: "); 
    scanf("%d", &(p->ssn)); 
    while((ch = getchar()) != '\n' && ch != EOF); 
} 

int main(){ 
    int i, size = 2; 
// printf("Input the number of people you wish to enter: "); 
// scanf("%d", &size); 
// while((ch = getchar()) != '\n' && ch != EOF); 
    struct person *parray[size]; 
    for(i = 0; i < size; i++){ 
    initParty(parray[i]); 
    getParty(parray[i]); 
    print(parray[i]); 
    } 
    //sort(parray, size); 
    printArray(parray, size); 
    return 0; 
}  
    return; 
} */ 

void initParty(struct person *p){ 
    p = (struct person*)malloc(sizeof(struct person)); 
    p->firstName = (char*)malloc(100 * sizeof(char)); 
    p->lastName = (char*)malloc(100 * sizeof(char)); 
} 

void getParty(struct person *p){ 
    int ch; 
    printf("\nEnter the firstname: "); 
    scanf("%s", p->firstName); 
    while((ch = getchar()) != '\n' && ch != EOF); 
    printf("\nEnter the lastname: "); 
    scanf("%s", p->lastName); 
    while((ch = getchar()) != '\n' && ch != EOF); 
    printf("\nEnter the ssn: "); 
    scanf("%d", &(p->ssn)); 
    while((ch = getchar()) != '\n' && ch != EOF); 
} 

int main(){ 
    int i, size = 2; 
// printf("Input the number of people you wish to enter: "); 
// scanf("%d", &size); 
// while((ch = getchar()) != '\n' && ch != EOF); 
    struct person *parray[size]; 
    for(i = 0; i < size; i++){ 
    initParty(parray[i]); 
    getParty(parray[i]); 
    print(parray[i]); 
    } 
    //sort(parray, size); 
    printArray(parray, size); 
    return 0; 
} 
+1

C11 Norm-Entwurf n1570: '6.5.2.2 Funktionsaufrufe, 4 Ein Argument kann ein Ausdruck eines beliebigen vollständigen Objekttypen sein. Bei der Vorbereitung des Aufrufs auf eine Funktion werden die Argumente ausgewertet, und jedem Parameter wird der Wert des entsprechenden Arguments zugewiesen. 93) Eine Funktion kann die Werte ihrer Parameter ändern, aber diese Änderungen können die Werte der Argumente nicht beeinflussen. C ist Call-by-Value. – EOF

+0

Ihr 'printArray()' Code sollte aus Prinzip die 'print()' Funktion aufrufen - obwohl es besser ist, das in 'printPerson()' umzubenennen. –

+1

Es gibt einige kritische Compiler-Warnungen und -Fehler, die behoben werden müssen. Zum Beispiel ist Ihre Verwendung von 'strcmp()' völlig falsch, und Sie haben nicht die relevante Kopfzeile '' mit eingeschlossen. – EOF

Antwort

0

Da die Beiträge wurden alle Kommentare und Antworten nicht, dass ich glaube, ich werde Beantworte das selbst. Das Problem ist, dass ich den Zeiger auf die Struktur an die Funktion übergeben habe, und daher hat die Struktur die Kopie des lokalen Zeigers geändert, da C ein Vorübergehender Wert ist. Wenn man das Objekt, auf das gezeigt wird, modifizieren möchte, muss der Zeiger referenziert werden, so dass das Hauptobjekt modifiziert werden kann, wenn es innerhalb der Funktion referenziert wird. Folgende Änderungen haben den Trick:

void initParty(struct person **p){ 
    *p = (struct person*)malloc(sizeof(struct person)); 
    (*p)->firstName = (char*)malloc(100 * sizeof(char)); 
    (*p)->lastName = (char*)malloc(100 * sizeof(char)); 
} 

und den Ruf:

initParty(&(parray[i])); 
+1

Beachten Sie, dass 'initParty (& parray [i]);' äquivalent zu dem ist, was Sie geschrieben haben; die inneren Klammern sind nicht notwendig oder konventionell, obwohl sie ansonsten harmlos sind. –

Verwandte Themen