如何在C中更改结构的属性大小?

时间:2017-03-09 18:36:13

标签: c malloc realloc

我是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;
}

当用户第一次输入姓名,电话号码和注释时,程序会自动停止工作,尽管它应该永远要求用户使用这些属性。

4 个答案:

答案 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.note
printf("note: %s\n",entry.note.str);