我无法弄清楚为什么我的程序输出看似随机的 Windows 路径,如下所示。
\maven, : ORS=4 (id: 4677968)
m32\cmd.exe, ò: Æ (id: 5525087)
, : (id: 4653392)
它在遍历我拥有的结构数组并显示其中的值时执行此操作。有趣的是,尽管它运行良好。如果我添加 5 个条目,它仍然会准确显示所有条目。然而,它会在其他所有内容之前打印上面显示的随机路径。
我将附上整个程序,因为老实说,我不知道将问题缩小到哪里。我是 C 新手,尤其是手动处理内存的新手。所以这可能就是问题所在。提前谢谢。
该程序:
#include<stdio.h>
#include<string.h>
// Define structures
typedef struct Contact
{
int id;
char fname[24];
char lname[24];
char number[16];
} Contact;
typedef struct Phonebook
{
Contact* contacts;
int contacts_length;
int id_tracking;
} Phonebook;
// Define prototypes
Phonebook addContact(Phonebook);
Phonebook removeContact(Phonebook); // removeContact() prompts the user for information about whom they want to remove.
void viewContacts(Phonebook);
void exportContacts(Phonebook);
Contact findEntry(int, Phonebook);
Phonebook removeEntry(int, Phonebook); // removeEntry() can be called to explicitly remove the entry with the passed in integer id.
int main()
{
// Define variables
int menuChoice = 0, status = 1;
Phonebook phonebook;
phonebook.contacts = (Contact*) malloc(sizeof(Contact));
// Check memory allocation
if(phonebook.contacts == NULL)
{
printf("\nFatal error: Out of memory... now exiting.");
return;
}
// Handle the user
do
{
// Begin collecting and assigning data
printf("\nContact Menu\n");
printf("\n(1.) Add contact");
printf("\n(2.) Remove contact");
printf("\n(3.) View contacts");
printf("\n(4.) Export contacts");
printf("\n(5.) Exit");
printf("\n\nPlease choose a menu option (enter the number): ");
scanf("%d", &menuChoice);
// Interpret menu choice
switch(menuChoice)
{
case 1:
// Begin adding contact
phonebook = addContact(phonebook);
status = 1;
break;
case 2:
phonebook = removeContact(phonebook);
status = 1;
break;
case 3:
viewContacts(phonebook);
status = 1;
break;
case 4:
exportContacts(phonebook);
status = 1;
break;
case 5:
// Free memory
free(phonebook.contacts);
// See ya!
printf("\nGoodbye!");
status = 0;
break;
default:
printf("I'm sorry, I didn't quite understand that. Please try again.");
status = 1;
break;
}
}
while(status != 0);
// Return 0 for exit
return 0;
}
Phonebook addContact(Phonebook phonebook)
{
// Clear screen first
system("cls");
// Define contact and set random id
Contact entry;
entry.id = phonebook.id_tracking;
phonebook.id_tracking++;
// Obtain information
printf("First name (24 characters max): ");
scanf("%s", &entry.fname);
printf("Last name (24 characters max): ");
scanf("%s", &entry.lname);
printf("Telephone number (recommended format: ###-###-####): ");
scanf("%s", &entry.number);
// Handle memory allocation
if(phonebook.contacts_length > 1)
{
phonebook.contacts = (Contact*) realloc(phonebook.contacts, sizeof(Contact) * (phonebook.contacts_length + 1));
}
// Save the contact to the array and count up
phonebook.contacts[phonebook.contacts_length] = entry;
phonebook.contacts_length++;
printf("Contact saved!\n");
return phonebook;
}
Phonebook removeContact(Phonebook phonebook)
{
// First check to make sure they have saved contacts
if(phonebook.contacts_length < 1)
{
// No contacts saved, tell them
printf("\nYou haven't saved any contacts.\n");
return;
}
// Define variables
int i, chosenId = 0;
// Display contacts with their ids
for(i = 0; i < phonebook.contacts_length; i++)
{
Contact entry = phonebook.contacts[i];
printf("\n%s, %s (id: %d)", entry.lname, entry.fname, entry.id);
}
// Handle removal
printf("\n\nPlease enter the ID of the contact you would like to remove: ");
scanf("%d", &chosenId);
// Remove
Phonebook updatedPhonebook = removeEntry(chosenId, phonebook);
printf("Contact removed!\n");
return updatedPhonebook;
}
void viewContacts(Phonebook phonebook)
{
// First check to make sure they have saved contacts
if(phonebook.contacts_length < 1)
{
// No contacts saved, tell them
printf("\nYou haven't saved any contacts.\n");
return;
}
// Define variables
int i;
// Display contacts with their ids
for(i = 0; i < phonebook.contacts_length; i++)
{
Contact entry = phonebook.contacts[i];
printf("\n%s, %s: %s (id: %d)", entry.lname, entry.fname, entry.number, entry.id);
}
printf("\n");
return;
}
/*
* Experimenting with I/O in C
*/
void exportContacts(Phonebook phonebook)
{
// First check to make sure they have saved contacts
if(phonebook.contacts_length < 1)
{
// No contacts saved, tell them
printf("\nYou have no contacts to be exported.\n");
return;
}
// Define and initialize variables
int i;
char outputName[] = "contacts.txt";
FILE *contactFile = fopen(outputName, "w");
// Print message
printf("\nExporting contacts to .txt file... ");
// Print to the file
for(i = 0; i < phonebook.contacts_length; i++)
{
Contact entry = phonebook.contacts[i];
fprintf(contactFile, "%s, %s (id: %d): %s\n", entry.lname, entry.fname, entry.id, entry.number);
}
// Close the file
fclose(contactFile);
// Done
printf("Done!");
printf("\nData exported to contacts.txt located where this program was launched.");
}
Contact findEntry(int id, Phonebook phonebook)
{
int i;
for(i = 0; i < phonebook.contacts_length; i++)
{
Contact entry = phonebook.contacts[i];
if(entry.id == id)
{
return entry;
}
}
}
Phonebook removeEntry(int id, Phonebook phonebook)
{
// Define variables
int i, positionToFree;
// Search for the index of the entry to remove
for(i = 0; i < phonebook.contacts_length; i++)
{
Contact entry = phonebook.contacts[i];
if(entry.id == id)
{
positionToFree = i; // This is the position to be freed
}
// We've found what we need, break now
break;
}
// Loop starting at that entry and remove
for(i = positionToFree; i < phonebook.contacts_length; i++)
{
Contact temp = phonebook.contacts[i + 1];
phonebook.contacts[i] = temp;
}
// Count down for contacts_length
phonebook.contacts_length--;
// Return the updated contacts
return phonebook;
}