2016-03-11 53 views
0

我想用字符串填充結構。困惑與結構和指針

struct person { 
    char *name 
    char age 
}; 

int record_values(struct person *dude, const char *his_name, char his_age) 
{ 
    dude->name = malloc(strlen(his_name)*sizeof(char)); //Get space for name 
    strcpy(dude->name, his_name);       //Set name 
    strcpy(dude->age, his_age);       //Set age 
} 

但是這不起作用。任何幫助?

+2

你是什麼意思的「不工作」? – Glapa

+1

@HimBromBeere這看起來更像是C而不是C++ –

+1

請告訴我們,您使用純C還是C++,可能會有不同的方法來完成這兩種語言之一。 – zaratustra

回答

3
dude->name = malloc(strlen(his_name)*sizeof(char)); //Get space for name 
strcpy(dude->name, his_name);       //Set name 
strcpy(dude->age, his_age);       //Set age 

您的第一行沒有分配足夠的空間。您需要一個字節的字符串終止符。

您的最後一行呼叫strcpy,但his_age不是字符串。

+0

你也需要在C++中進行強制轉換(所以最好使用new),而sizeof(char)就是一個簡單的噪音。 – SergeyA

0
int record_values(struct person *dude, const char *his_name, char his_age) 
{ 
    dude->name = strdup(his_name); // Duplicate name 
    dude->age = his_age;    // Set age (Simple assignment!) 
} 
0

而不是指出你應該改變你的代碼在這裏的一個完整的工作示例,希望顯示所需的差異。下面的代碼首先創建一個struct person,但是當調用函數record_values()時,您會看到它首先必須檢查dude-name是否已經指向char數組。沒有這個檢查會在您的代碼中創建內存泄漏,並且以前的dude->name將永遠不會被釋放。它還爲字符串終結符在char數組中分配了一個額外的char空間(strcpy也會複製它)。這將避免溢出錯誤。該函數不返回任何內容,因此使其成爲void函數而不是返回int的函數。 dude->age的值不是指向內存空間的指針,因此不應使用strcpy,而應使用dude->age = his-age,它複製變量的值。

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

struct person { 
    char *name; 
    char age; 
}; 

struct person * record_alloc(const char *his_name, char his_age); 
void   record_values(struct person *dude, const char *his_name, char his_age); 
void   record_free(struct person * dude); 


struct person * record_alloc(const char *his_name, char his_age){ 
    struct person * dude; 

    dude = malloc(sizeof(struct person)); 
    if (his_name != NULL){ 
     record_values(dude, his_name, his_age); 
    } else { 
     dude->age = 0; 
     dude->name = NULL; 
    } 
    return dude; 
} 

void record_values(struct person *dude, const char *his_name, char his_age) 
{ 
    size_t nameSize; 

    if (dude->name) 
     free(dude->name); 

    nameSize = (strlen(his_name) + 1) * sizeof(char); 
    dude->name = malloc(nameSize); 
    strcpy(dude->name, his_name); 
    dude->age = his_age; 
    return; 
} 

void record_free(struct person * dude){ 
    if (dude->name) 
     free(dude->name); 

    free(dude); 
    return; 
} 

int main(int argc, const char * argv[]) { 
    struct person * p; 

    // allocate and set values 
    p = record_alloc("John Smith", 32); 
    printf("%s is %i years old\n", p->name, p->age); 

    // set new values for p 
    record_values(p, "John Doe", 37); 
    printf("%s is %i years old\n", p->name, p->age); 

    // free p 
    record_free(p); 

    return 0; 
} 
+0

根據定義,sizeof(char)總是等於1,所以只需使用'nameSize = strlen(his_name)+ 1' – FredK

0

你可能更願意使用designated initializers

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

typedef struct { 
    char *name; 
    char age; 
} person; 

int record_values(person *dude, const char *his_name, char his_age) 
{ 
    *dude = (person) {.name = strdup(his_name), .age = his_age}; 
} 

int main() 
{ 
    person p; 
    record_values(&p, "bob", 27); 
    printf("Hello, I am %s and I am %d years old!\n", p.name, p.age); 
    return 0; 
} 

你好,我是鮑勃和我27歲!

由於的strdup是not a part of c99你的編譯器可能會產生警告,擺脫他們的需要與-std=gnu99編譯它:

gcc -std=gnu99 -o main *.c 

或使用您自己的版本的這一點,這可能是這樣的:

#include <stdlib.h> 
char * strdup(const char *in) { 
    char *out = malloc(sizeof(in) + 1); 
    int i; 
    for (i = 0; in[i] != '\0'; ++i) 
     out[i] = in[i]; 
    return out; 
}