简体   繁体   English

与指针一起使用嵌套结构

[英]Using nested struct with with Pointers

I have an exercise in which I have to print the list of the document's names that exists in a Folder. 我有一个练习,必须打印文件夹中存在的文档名称列表。

By the program i can type detailes for each new document including Document's name. 通过该程序,我可以为每个新文档键入详细信息,包括文档名称。 Basicly i have to build 2 structs : 基本上我必须建立2个结构:

  • one for the Document's detailes 一个用于文档的详细信息
  • and the other one for the Folder 另一个用于文件夹

In Folder's struct there is a nested struct that should contain the Document's details ( Document struct ). 在Folder的结构中,有一个嵌套的结构,其中应包含Document的详细信息( Document struct )。 For my understanding i have to store each document's detailes in the Folder. 据我了解,我必须将每个文档的详细信息存储在Folder中。

My question is how can I store the document's detais in the Folder and how can I print by using PrintFolderDetails function. 我的问题是如何将文档的详细信息存储在文件夹中,以及如何通过使用PrintFolderDetails函数进行打印。 Is it correct to write double astrics by writing : struct document **docs ; 通过编写以下内容来写双斜体是否正确: struct document **docs ;

I've tried to assign in option 4 after copying the document but i get the message: 复制文档后,我尝试在option 4进行分配,但出现以下消息:

access violation reading location... 访问冲突阅读位置...

Here is my Code: 这是我的代码:

#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);
        }
    }
}

In case 4 you are allocating numOfDocuments size array, meaning the range of the array is 0 to numOfDocuments-1 - so in the next line you should not access docs[numOfDocuments] , you probably meant to use docs[numOfDocuments-1] 在情况4中,您正在分配numOfDocuments size数组,这意味着数组的范围是0numOfDocuments-1因此,在下一行中,您不应访问docs[numOfDocuments] ,您可能打算使用docs[numOfDocuments-1]

Regardless, you have several other issues in the code. 无论如何,代码中还有其他几个问题。 Just in the following line for example: 例如在下面的行中:

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

It should be 它应该是

folder->docs= malloc(sizeof(Folder *)*numOfDocuments)
  1. Use p-> instead of (*p) - it is just semantic, but it is the common way. 使用p->代替(* p)-这只是语义,但这是常见的方式。
  2. Don't cast return value of malloc 不要转换malloc的返回值
  3. The correct size should be of (Folder*) - it has no affect in your case, because size of pointer is the same size of pointer to pointer, but it is wrong to do it that way. 正确的大小应为(Folder *)-在您的情况下不会有任何影响,因为指针的大小与指向指针的指针的大小相同,但是这样做是错误的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM