我正在做一本书练习(不是家庭作业,因为我是自学),我应该使用类型结构的数组编写电话簿。 所以我定义了:
typedef struct contact {
char cFirstName[10];
char cLastName[10];
char iTelphone[12];
} address ; // end type
接下来,我定义了:
address myContacts[5] = {
{
{ '\0' } // inner most braces,
// tell gcc to put 0 in all
// members of each struct ?
} // first braces, tell gcc we have a
// a struct as array member
}; // outer most braces, tell gcc we have
// an array
现在我有一个打印数组内容的函数。 但是,我不想打印所有阵列,因为我只对此感兴趣 数组元素中的成员不是空的。所以我尝试了以下内容:
void printContacts( address * myContacts ){
printf("Inside printContacts");
int i = 0;
while ( i < 5 ) {
if (myContacts[i].cFirstName == NULL )
printf("%s", myContacts[i].cFirstName); //does not work
if (myContacts[i].cFirstName == '\0' )
printf("%s", myContacts[i].cFirstName); //does not work
if (myContacts[i].cFirstName[0] != 0 )
{
printf("%s", myContacts[i].cFirstName ); //does work!
}
i++;
}
}
所以,我的问题是:
提前感谢您的回答!
答案 0 :(得分:2)
你的ïnitialization方法在某种程度上是不寻常的,因为它基本上将结构归零,memset(&MyContacts,0,sizeof(address)*5)
你可以将结构中的所有东西都置为NULL。
您无法检查数组是否为“空”,因为NULL在一般情况下是有效元素。如果确定只有一个C字符串将包含在数组中,那么您只需要检查第一个元素是否为NULL。由于所有C字符串始终以NULL结尾,这意味着您必须始终在字符串末尾添加终止NULL。
答案 1 :(得分:2)
所以,我的问题是:
Am I initializing the array elements members to be really null (e.g cFirstName[10]) ? Is there a better way ? How can I check that an array element member is empty ?
提前感谢您的回答!
您在初始化struct数组时所做的工作可以改进。
第一个括号说,“用我的内容初始化数组:”
解决myContacts [5] = {...}
第二组括号表示“使用以下内容初始化数组中的第一个结构:”
address myContacts[5] = {
{ ... } , // each of these braces initializes a different struct in the
{ ... } , // array (there are five inner brace sets as there are five
{ ... } , // structs in the array).
{ ... } ,
{ ... }
}
请注意,一次初始化所有数组元素或使用它是一种很好的形式 这样做的for循环。这就是你原来的初始化让我困惑的原因;我不确定它是“正确的”,即使它运行。
然后,你在那些内部放置了更多的括号(如果你仍然想为这个应用程序进行大括号初始化)来初始化结构中的数组:
address myContacts[5] = {
{{'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'},
{'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'},
{'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0, '\0', '\0'} },
.
.
.
}
这是使用括号表示法首先将阵列“清零”的方法。没有太多人这样做;它变得单调乏味。通常,对于一个真正的应用程序,人们会使用堆(你可以动态分配的内存,如下所示)这样的东西,在这种情况下你可以简单地在结构中使用指针:
typedef struct contact {
char *cFirstName;
char *cLastName;
char *iTelphone;
} address ; // end type
然后您将分配联系人列表:
address *myContacts = (address*) malloc(sizeof(address)*5);
// the above allocates a five-element array
int i;
for (i = 0; i < 5; i++)
{
myContacts[i].cFirstName = NULL;
myContacts[i].cLastName = NULL;
myContacts[i].iTelephone = NULL;
}
在需要添加到地址簿时分配字符串:
myContacts[0].cFirstName = (char*) malloc(sizeof(char)*20);
strcpy(myContacts[0].cFirstName,"Tom, Dick, or Harry");
当你完成后,释放你分配的所有内容:
int i;
for (i = 0; i < 5; i++)
{
if (myContacts[i].cFirstName != NULL) // since we initialized all pointers
{ // to null, this only isn't null when
free(myContacts[i].cFirstName); // it's been previously allocated
}
if (myContacts[i].cLastName != NULL)
{
free(myContacts[i].cLastName);
}
if (myContacts[i].iTelephone != NULL)
{
free(myContacts[i].iTelephone);
}
}
这允许您创建可变长度的字符串,任意大的联系人列表,如果要检查条目是否为空,只需检查它的指针是否为空:
if (myContacts[i].cFirstName != NULL)
{
printf("%s", myContacts[i].cFirstName ); //does work!
}
我希望这个概念至少证明对你有用,即使你最终没有使用malloc(在每个程序中有充分的理由支持或反对使用它)。 :)
答案 2 :(得分:1)
你实际上是用0
创建你的struct和paddint,因此条件myContacts[i].cFirstName == NULL
永远不会成为真,因为你正在创建一个静态数组,它只有在你声明{{{ 1}}作为结构中的指针(cFirstName
)。
此外,您的第二个条件与第一个条件基本相同,因为char*
只是NULL
的预处理器常量。
要测试字符串是否为空,通常将第一个字符与0进行比较,就像上次测试一样。
答案 3 :(得分:1)
我是否将数组元素成员初始化为真正的空(例如cFirstName [10])?
您基本上将字符串缓冲区的第一个字符分配给'\ 0'(或等效地为0.)
例如,下面的name
变量的值是指指向字符串缓冲区的指针。因此,在这种情况下,如果将指针与0或'\ 0'进行比较,则它们将不相等。
int i;
char name[10] = {'\0'};
printf("Raw content: ");
for(i = 0 ; i < 10 ; ++i)
printf("%2d ", name[i]);
printf("\n\n");
printf("name = %p\n\n", name);
printf("*name = %d, name[0] = %d\n\n", *name, name[0]);
这给出了:
Raw content: 0 0 0 0 0 0 0 0 0 0
name = 0012FF48
*name = 0, name[0] = 0
如果名称设置为“Hello”:
Raw content: 72 101 108 108 111 0 0 0 0 0
name = 0012FF48
*name = 72, name[0] = 72
有更好的方法吗?
不确定我的问题是否正确:为了确保数组x的每个元素都设置为y值,您可以使用memset
函数。
如何检查数组元素成员是否为空?
要检查空字符串,可以使用strlen
函数找出'\ 0'终止字符串的长度。
答案 4 :(得分:0)
您应该检查myContacts[i].cFirstName[0]
,因为myContacts[i].cFirstName
是指向char
数组的指针。
详细解释
对于您的第一个问题:是的,您已经将myContacts
的所有元素初始化为空。前两个测试失败的原因是myContacts[i].cFirstName
是指向char
数组的指针,而不是NULL
。定义myContacts
数组时,它位于堆栈上,myContacts[i]
指向堆栈上的某个位置/地址,而不是NULL
。
第二种:您也可以通过
初始化数组address myContacts[5]; // define an address array with 5 elements
memset((void*)myContacts, 0, sizeof(myContacts));
但不知道哪一个效率更高。