我是C编程的新手,我需要创建一个电话簿。每个条目必须包含姓名,电话号码和备注部分。事实是,音符部分的大小应根据输入而改变。例如,如果用户输入一个包含30个字符的字符串,则note的大小应为30.我无法弄清楚如何操作。
到目前为止,这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <note>
struct Entries {
char name[50];
char phoneNumber[11];
char * note;
note = (char *)malloc(5*sizeof(char));
}Entries;
int main()
{
int command;
int counter = 0;
char tempNote[50];
char tempName[50];
char tempPhoneNumber[11];
while(1){
printf("Welcome to myPhoneBook! Please select an option:\n 1) New entry\n 2) List all entries\n 3) Edit\n 4) Delete\n 5) Search\n");
scanf("%d", &command);
if(command == 1){
struct Entries entry;
printf( "Enter a name:\n");
scanf("%s",tempName);
strcpy(entry.name, tempName);
printf( "Enter a phone:\n");
scanf("%s",tempPhoneNumber);
strcpy(entry.phoneNumber, tempPhoneNumber);
printf( "Enter a note:\n");
scanf("%s",tempNote);
entry.note = (char *)realloc(entry.note,strlen(tempNote));
strcpy(entry.note, tempNote);
counter++;
}
}
return 0;
}
当用户第一次输入姓名,电话号码和注释时,程序会自动停止工作,尽管它应该永远要求用户使用这些属性。
答案 0 :(得分:2)
您可以使用flexible array member。这是更好的方法。
引用C11
标准,章节§6.7.2.1
[...]具有多个命名成员的结构的最后一个元素可以 有一个不完整的数组类型;这被称为灵活的阵列成员。在大多数情况下, 灵活的数组成员被忽略。特别是,结构的大小就像是 省略了灵活的数组成员,除了它可能有更多的尾随填充 遗漏意味着。但是,当
.
(或->
)运算符具有左操作数时 (指向)具有灵活数组成员和右操作数名称的结构 成员,它的行为好像该成员被替换为最长的数组(具有相同的 元素类型)不会使结构大于被访问的对象;该 数组的偏移量应保持灵活阵列成员的偏移量,即使这会有所不同 从替换阵列的。如果此数组没有元素,则表现得好像 它有一个元素,但如果有任何尝试访问它,行为是未定义的 元素或生成一个经过它的指针。
和示例
示例2声明后:
struct s { int n; double d[]; };
结构
struct s
具有灵活的数组成员d
。使用它的典型方法是:int m = /* some value */; struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));
并假设对
malloc
的调用成功,p
指向的对象在大多数情况下表现得好像p
已被声明为:struct { int n; double d[m]; } *p;
现在,按照上述步骤,您可以扫描输入,使用输入长度m
,然后分配足够的内存来保存输入。
答案 1 :(得分:0)
替换
entry.note = (char *)realloc(entry.note,strlen(tempNote));
与
entry.note = malloc(strlen(tempNote) + 1);
另外
删除
note = (char *)malloc(5*sizeof(char)
struct
定义的。它不属于那里。
答案 2 :(得分:0)
我建议先学习C的基础知识。 C实际上只是一个带宏的便携式汇编程序。在完成任何事情之前,你绝对需要知道指针和内存分配是如何工作的:)
顺便说一下,祝贺你开始学习C,这将为你提供很多关于计算机和编程语言本质的深刻见解:):))
答案 3 :(得分:0)
关闭,
如果用户输入一个包含30个字符的字符串,则应注明大小 30。
C中的字符串以空值终止,因此您需要为终端字符保留空格(&#39; \ 0&#39;)。您可以将字符串存储为字符串的长度和字符,但是您需要确定可表达的最大字符数。
最简单的方法是使用strdup()为字符串和null终止符分配足够的空间。
if( entry.note ) free(entry.note); //avoid leaking memory
entry.note = strdup(tempNote);
或者你可以使用包含长度和数据的结构,分配,分配和释放使用以下内容,
typedef struct {
unsigned short int len;
char str[1];
} strwlen_t;
strwlen_t* string_withlen_alloc(unsigned short int size) {
strwlen_t* p = malloc( size + sizeof(strwlen_t) );
p->str[0] = '\0';
p->len = 0;
return p;
}
strwlen_t* strwlen_dup(char* str) {
unsigned short int len = strlen(str);
strwlen_t* p = malloc( len + sizeof(strwlen_t) );
memcpy(p->str,str);
p->len = len;
return p;
}
void strwlen_free(strwlen_t* p) {
free(p);
}
strwlen_t* strwlen_cpy(strwlen_t* dp,char* sp) {
strcpy(dp->str,sp);
dp->len = len(sp);
return(dp);
}
声明您的条目结构
struct Entries {
char name[50];
char phoneNumber[11];
strwlen_t* note;
} Entries;
然后你可以使用,
if( entry.note ) free(entry.note);
entry.note = strwlen_dup(tempNote);
并使用
打印entry.noteprintf("note: %s\n",entry.note.str);