0

我无法弄清楚为什么我的程序输出看似随机的 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;
}
4

1 回答 1

0

这听起来像是未定义的行为。

你永远不会初始化phonebook.contacts_length. 它可以有任何价值。当你去添加一个条目时,很可能realloc调用失败。你不检查返回值,所以你不会知道。

坏朱朱。

于 2013-10-18T01:28:46.967 回答