2016-03-11 119 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; 
}