这是我从代码片段中读取文件和createClient的值的代码片段。我有一组客户端,我给不同的数组元素赋予不同的值。
FILE *clientFile;
clientFile = fopen("clients.txt", "r");
char id[256];
char name[256];
char phone[256];
char email[256];
Client cptrs[10];
int i=0;
while(fgets(id, sizeof(id), clientFile)){
//fscanf(clientFile, "%s", name);
fgets(name, sizeof(name), clientFile);
fgets(phone, sizeof(phone), clientFile);
fgets(email, sizeof(email), clientFile);
/*fscanf(clientFile, "%s", phone);
fscanf(clientFile, "%s", email);*/
//printf("%s %s %s %s\n", id,name,phone,email);
cptrs[i] = createClient(id,name,phone,email);
//printc(cptrs[i]);
//printf("%d\n", i);
i++;
}
printc(cptrs[0]);
printc(cptrs[1]);
printc(cptrs[2]);
所有3个打印功能输出的结果与文件中的最后一个数据相同。
这是struct client,createClient方法和printc方法。我已经包含了client.h和client.c文件。
client.h
#ifndef CLIENT_H
#define CLIENT_H
typedef struct client *Client;
Client createClient(char* id, char* name, char* phone, char* email);
void destroyClient(Client cP);
void printc(Client cP);
#endif
client.c
#include "client.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct client {
char* id;
char* name;
char* phone;
char* email;
};
// returns the pointer to the list; NULL if list not created
Client createClient(char* id, char* name, char* phone, char* email) {
// allocate memory for a structure variable containing all
// list components
Client cptr = malloc(sizeof(struct client));
// if allocation was succesfull
if (cptr != NULL) {
cptr->id = id;
cptr->name = name;
cptr->phone = phone;
cptr->email = email;
}
return cptr;
}
void destroyClient(Client cptr) {
free(cptr);
}
void printc(Client cptr){
printf("%s %s %s %s\n", cptr->id, cptr->name, cptr->phone, cptr->email);
}
这是clients.txt文件
1212
Joseph Miller
206-555-1212
millers@comcast.net
1313
Beatrice Pizarro Ozuna
206-111-1111
bea@uw.edu
1314
Anne Simpson
425-777-8888
a.simpson@gmail.com
1100
Emily Price
206-111-5555
priceless@yahoo.com
1289
Sharon Henderson
206-555-1289
henderson21@comcast.net
1316
Sylvia Williamson
425-123-8888
sylvia@gmail.com
1101
Michael Murphy
425-111-5555
gemini@yahoo.com
第一个代码的输出是:
1101
Michael Murphy
425-111-5555
gemini@yahoo.com
1101
Michael Murphy
425-111-5555
gemini@yahoo.com
1101
Michael Murphy
425-111-5555
gemini@yahoo.com
我不明白为什么所有数组元素都存储相同的元素(文件中的最后一个元素)。我希望他们存储各自的元素。请帮忙。
答案 0 :(得分:2)
在createClient中,您需要复制您在参数中传递的字符串,因为它们实际上是指向您在第一个片段中声明的静态字符缓冲区的指针。这些会在你的while循环中的每次迭代中被覆盖。
尝试:
if (cptr != NULL) {
cptr->id = strdup(id);
cptr->name = strdup(name);
cptr->phone = strdup(phone);
cptr->email = strdup(email);
}
在destroyClient中,确保释放strdup隐式分配的内存:
void destroyClient(Client cptr) {
free(cptr->id);
free(cptr->name);
free(cptr->phone);
free(cptr->email);
free(cptr);
}
答案 1 :(得分:1)
下面
Client createClient(char* id, char* name, char* phone, char* email) {
// allocate memory for a structure variable containing all
// list components
Client cptr = malloc(sizeof(struct client));
// if allocation was succesfull
if (cptr != NULL) {
cptr->id = id;
cptr->name = name;
cptr->phone = phone;
cptr->email = email;
}
return cptr;
}
您只需指定输入指针值,例如id,给新客户。由于createClient
的所有调用都传递了来自main
的相同指针,因此结果是所有创建的客户端都包含指向main中相同变量的指针。
您需要为每个内存分配新内存并将数据复制到已分配的内存中。类似的东西:
Client createClient(char* id, char* name, char* phone, char* email) {
// allocate memory for a structure variable containing all
// list components
Client cptr = malloc(sizeof(struct client));
// if allocation was succesfull
if (cptr != NULL) {
cptr->id = malloc(256); // Allocate memory
strcpy(cptr->id, id); // Copy data to the new memory
// ... and so on
}
return cptr;
}
注意:为了使示例简单,我跳过检查malloc
返回NULL。您应该在strcpy
另请注意,您需要更改destroyClient
,以便释放所有内存,例如free(cptr->id)
。
另一种方法:
当您处理相当少量的内存时,可能值得考虑避免struct client
中的指针,而是:
struct client {
char id[256];
char name[256];
char phone[256];
char email[256];
};
然后你可以使用malloc
中的一个createClient
,然后strcpy
(甚至是memcpy
)。