我正在处理此代码,但尚未完成。但是在测试添加新的联系人功能和打印功能时,我得到了这个奇怪的输出。只要我没有添加多个联系人,Everythin看起来就好了。我在这里做错了什么?
//Libraries:
#include <stdio.h>
#include <stdlib.h>
//Function prototypes
int showMenu(); //Shows user options
//Main function
int main() {
//Variable declerations
int i = 0;
int iOption = 0;
int iContacts = 0;
char *cPhoneBook_name;
int *iPhoneBook_nr;
cPhoneBook_name = (char *) calloc(1, 80 * sizeof(char));
iPhoneBook_nr = (int *) calloc(1, sizeof(int));
do {
//Memory check
if(cPhoneBook_name == NULL || iPhoneBook_nr == NULL){
printf("\nOut of Memory!\n");
return;
}
//Show menu
iOption = showMenu();
switch (iOption) {
case 1: //Add contact
printf("\nEnter name:\n");
scanf("%s", &cPhoneBook_name[iContacts]);
printf("\nEnter number:\n");
scanf("%d", &iPhoneBook_nr[iContacts]);
cPhoneBook_name = realloc(cPhoneBook_name, 80 * sizeof(char));
iPhoneBook_nr = realloc(iPhoneBook_nr, sizeof(int));
iContacts += 1;
break;
case 2: //Modify contact
//Code here
break;
case 3: //Show contacts
for(i = 0 ; i < iContacts ; i++) {
printf("\n%s %d\n", &cPhoneBook_name[i], iPhoneBook_nr[i]);
}
break;
case 4: //Free memory (delete contacts)
free(cPhoneBook_name);
free(iPhoneBook_nr);
break;
}
}while(iOption != 5);//Exit if iOption is 5;
system("clear");
return 0;
}
//Function definition - showMenu()
int showMenu() {
int iOption = 0;
//system("clear");
printf("\n Phone book \n");
printf("------------------------\n");
printf("1. Add new contact.\n");
printf("2. Edit existing contact\n");
printf("3. Show contact(s)\n");
printf("4. Clear phone book\n");
printf("5. Exit\n");
printf("------------------------\n");
printf("Option --> ");
scanf("%d", &iOption);
return iOption;
}
//---------------------------------------------------------
答案 0 :(得分:2)
问题在于:
printf("\n%s %d\n", &cPhoneBook_name[i], iPhoneBook_nr[i]);
{p> cPhoneBook_name
如果是char[]
类型。例如,表达式char[1]
为您提供列表中的第二个字符。虽然代码中的名称宽度为char
。所以试试:
printf("\n%s %d\n", &cPhoneBook_name[i*80], iPhoneBook_nr[i]);
我也发现了这个:
cPhoneBook_name = realloc(cPhoneBook_name, 80 * sizeof(char));
无效,因为您要将cPhoneBook_name
的大小从80调整为80。
尝试:
cPhoneBook_name = realloc(cPhoneBook_name, (iContacts+1) 80 * sizeof(char));
还有: scanf(&#34;%s&#34;,&amp; cPhoneBook_name [80 * iContacts]);
答案 1 :(得分:2)
这很可能是你&#34;奇怪的输出&#34;的根源。当您输入多个联系人时:
cPhoneBook_name = realloc(cPhoneBook_name, 80 * sizeof(char));
您实际上并未扩展cPhoneBook_name
数组的大小;在realloc
调用中,第二个参数是数组的新大小,而不是要添加到现有大小的数量。
话虽如此,这整个方法都是错误的;如果您没有创建字符串数组,那么每次添加联系人时都会创建一个扩展的单个字符串(不成功),并且iContacts
索引将指向i
字符串的字符,而不是字符串列表中的i
&#39;字符串。
这是一种应该有效的方法:
#define ROWS 5 // start with 5 rows in your contact list
// Create a type to store a single phone book entry
struct PhoneBookEntry {
char name[80]; // fixed size to keep things simple
int number;
};
// Create an array that can initially store ROWS
// phone book entries
struct PhoneBookEntry *phoneBook = malloc ( sizeof *phoneBook * ROWS );
size_t phoneBookRows = ROWS;
...
case 1: // Add contact
// Before adding a contact, see if we need to extend the phone book
// array
if ( iContacts == phoneBookRows )
{
// double the size of the phone book array
struct PhoneBookEntry *tmp = realloc( phoneBook, 2 * sizeof *phoneBook * phoneBookRows );
if ( tmp )
{
phoneBook = tmp;
phoneBookRows *= 2;
}
else
{
fprintf( stderr, "Could not extend phone book!\n" );
break;
}
}
...
scanf( "%s", phoneBook[iContacts].name ); // note no & operator; arrays are special
...
scanf( "%d", &phoneBook[iContacts].number );
有些注意事项:
首先,不要在C代码中投射malloc
,calloc
或realloc
的结果;这是不必要的,在C89编译器下可以掩盖错误。您做需要在C ++代码中强制转换这些函数的结果,但如果您正在编写C ++,那么您不应该使用malloc
,calloc
,或者realloc
无论如何。
其次,避免使用类型名称作为sizeof
参数来帮助它。请改用以下内容:
T *p = malloc( N * sizeof *p );
表达式的类型 *p
为T
,因此sizeof *p
相当于sizeof (T)
。这样,malloc
将始终分配正确的内存量,而不管T
,如果您决定更改T
,则只需在一个位置进行更改。
第三,realloc
如果无法满足请求,将返回NULL
;如果您将NULL
分配给phoneBook
变量,则会丢失对已分配的内存的引用。将realloc
的结果分配给临时变量,测试NULL
,然后将其分配给phoneBook
变量更安全。
第四,realloc
电话费用可能很昂贵,所以当你感觉这样做时,你想要最小化它们。将阵列的大小加倍是一种常见技术。