簡體   English   中英

與指針一起使用嵌套結構

[英]Using nested struct with with Pointers

我有一個練習,必須打印文件夾中存在的文檔名稱列表。

通過該程序,我可以為每個新文檔鍵入詳細信息,包括文檔名稱。 基本上我必須建立2個結構:

  • 一個用於文檔的詳細信息
  • 另一個用於文件夾

在Folder的結構中,有一個嵌套的結構,其中應包含Document的詳細信息( Document struct )。 據我了解,我必須將每個文檔的詳細信息存儲在Folder中。

我的問題是如何將文檔的詳細信息存儲在文件夾中,以及如何通過使用PrintFolderDetails函數進行打印。 通過編寫以下內容來寫雙斜體是否正確: struct document **docs ;

復制文檔后,我嘗試在option 4進行分配,但出現以下消息:

訪問沖突閱讀位置...

這是我的代碼:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LENGTH 100

typedef struct document
{
    char *docName;
    int  linesAmountInDoc;
    char **docContent;
}Document;

typedef struct folder
{
    char folderName[20];
    struct document **docs;
}Folder;

void NewFolder();
void MainMenu();    
Document *NewDocument(char *);
void EditDocument(Document *);
void PrintDocument(Document *);
Document *CopyDocument(Document *, int numOfDocuments);
void DeleteDocument(Document *);
void ListDocsInFolder();
void PrintFolderDetailes(Folder *fldr, int numOfDocuments); 


void main()
{
    NewFolder();
    MainMenu();
}


//Creates the new Folder
void NewFolder()
{
    Document *docs =(Document *)malloc(sizeof(Document));
    Folder *folder=(Folder *)malloc(sizeof(Folder));
    char *foldName;
    int folderSize;

    foldName=(char *)malloc(sizeof(char )*20);
    printf("Please enter the Folder's name : ");
    scanf("%s", foldName);
    strcpy(folder->folderName, foldName);
    printf("How many documents do you want in your Folder : ");
    scanf("%d", &folderSize);

    folder->docs=(Document **)malloc(sizeof(Document )*folderSize);

    PrintFolderDetailes(folder, folderSize);

    printf("A new Folder has been created \n ");
}


void MainMenu()
{
    char quit ;
    int menuOption, numOfDocuments=0;
    Document *doc=(Document *)malloc(sizeof(Document));
    Document *copyDoc=(Document *)malloc(sizeof(Document));
    Folder *folder=(Folder *)malloc(sizeof(Folder));
    //folder->docs= (Document **)malloc(sizeof(Document)*10);
    do
    {
        printf("\nWelcom to Document System \n");
        printf("1. Create Docuent \n");
        printf("2. Edit Document \n");
        printf("3. Print Document \n");
        printf("4. Copy Document \n");
        printf("5. Delete Document \n");
        printf("6. Show List of Documents in Folder \n");
        printf("\nChoose one of the Options above : ");
        scanf("%d", &menuOption);

        switch(menuOption)
        {
        case 1:
            printf("Enter your Document name : ");
            doc->docName=(char *)malloc(sizeof(char *)*LENGTH);
            scanf("%s", doc->docName);
            doc=NewDocument(doc->docName); 
            break;
        case 2:
            EditDocument(doc);
            break;
        case 3:
            PrintDocument(doc);
            break;
        case 4:
            numOfDocuments+=1;
            copyDoc=CopyDocument(doc, numOfDocuments);
            (*folder).docs=(Folder **)malloc(sizeof(Folder **)*numOfDocuments);              
            strcpy((*folder).docs[numOfDocuments]->docName, copyDoc->docName); //access violation            
            //strcpy(folder->docs[numOfDocuments].docName,copyDoc->docName);   //access violation   
            break;
        case 5:
            DeleteDocument(doc);
            break;
        case 6:
            PrintFolderDetailes(folder, numOfDocuments);
            break;
        default:
            scanf("%c", &quit) ;
            break;
        }

        quit=getchar();
        //getchar();

    }while (quit != 'q');
}


Document* NewDocument(char *docName)
{
    Document *newDocument;
    newDocument=(Document*)malloc(sizeof(Document));
    newDocument->docName= docName;
    newDocument->linesAmountInDoc=0;
    newDocument->docContent=(char **)malloc(sizeof(char));
    return newDocument;
}

void EditDocument(Document *document)
{
    int i;
    printf("Please enter How many lines do you want to write ? ");
    scanf("%d", &(*document).linesAmountInDoc);
    printf("You can write %d lines in your Document \n ",    
    (*document).linesAmountInDoc-1);
    //The number of lines in Document
    (*document).docContent=(char **)malloc(sizeof(char **)*(*document).linesAmountInDoc);  

    printf("Please enter the content of the Document \n");
    for(i=0;i<document->linesAmountInDoc;i++)
    {
        (*document).docContent[i]=(char *)malloc(sizeof(char *)*LENGTH);     
        //the length of each line
        //scanf("%s", (*document).docContent[i]); //Typing the sentence without spaces between words
        gets((*document).docContent[i]);
    }
}

void PrintDocument(Document *document)
{
    int i=0;
    printf("Document name : ");
    printf("%s \n", document->docName);
    puts("========================");
    for(i=0;i<(*document).linesAmountInDoc;i++)
    {
        printf("%s\n", (*document).docContent[i]);
    }
}

Document *CopyDocument(Document *document, int numOfDocuments)
{
    char *documentName=(char *)malloc(sizeof(char)*8);
    char *documentNumber=(char *)malloc(sizeof(char)*2);
    char *documentNameAndNumber=(char *)malloc(sizeof(strlen(document->docName)+1));

    strcpy(documentName, document->docName);
    sprintf(documentNumber, "%d" , numOfDocuments) ;    //casting the document's serial number to characters
    strcpy(documentNameAndNumber, documentName);
    strcat(documentNameAndNumber, documentNumber);      //concatenate the document's name & number
    strcpy(document->docName, documentNameAndNumber);   //Good!!!

    //For checking the copying results
    PrintDocument(document);
    printf("The Document has been copied \n");
    return document;
}


void DeleteDocument(Document *document)
{
    free((*document).docName);
    free((*document).docContent);

    free(document);
    document=NULL;

    printf("The tow Documents has been deleted");
}


void PrintFolderDetailes(Folder *folder, int numOfDocuments)
{
    int i=0;

    printf("Folder name : ");
    printf("%s \n", folder->folderName);
    puts("========================");

    if(numOfDocuments==0)
    {
        printf("The Folder %s is empty \n", folder->folderName);
        return;
    }
    else
    {
        for(i=0;i<numOfDocuments;i++)
        {
            //strcpy((*folder).docs[i].docName,doc->docName);
            printf("%s\n", (*folder).docs[i]->docName);
        }
    }
}

在情況4中,您正在分配numOfDocuments size數組,這意味着數組的范圍是0numOfDocuments-1因此,在下一行中,您不應訪問docs[numOfDocuments] ,您可能打算使用docs[numOfDocuments-1]

無論如何,代碼中還有其他幾個問題。 例如在下面的行中:

(*folder).docs=(Folder **)malloc(sizeof(Folder **)*numOfDocuments)

它應該是

folder->docs= malloc(sizeof(Folder *)*numOfDocuments)
  1. 使用p->代替(* p)-這只是語義,但這是常見的方式。
  2. 不要轉換malloc的返回值
  3. 正確的大小應為(Folder *)-在您的情況下不會有任何影響,因為指針的大小與指向指針的指針的大小相同,但是這樣做是錯誤的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM