2017-05-04 112 views
-1

我有一個打印出樹的函數printtree。 我在互聯網上的很多地方搜索過,我發現mmap是分配內存並寫入文件的好方法。使用MMAP將輸出打印到文件

我想使用mmap將printtree的內容打印到文件中。我第一次學習mmap,我不知道該怎麼做。

printtree()如下:

void printtree(struct Node *root, int indent) 
{ 
int i; 
     if(root != NULL) 
     { 
       printtree(root->right,indent + 1); 
       for(i = 0;i<indent;i++) 
       { 
         printf("\t"); 
       } 
       printf("%d\n",root->key); 
       printtree(root->left,indent + 1); 
     } 
} 

在我的main.c,我想這一點:

struct Node *root = NULL; 
     int  info ; 
     int  *arr; 
     int  choice; 
     int  fd; 
     int  mode = 0x0777; 
     struct stat mystat; 
     void *p; 
     int  size; 
     FILE *file_ptr; 
     if (argc != 2){ printf("Error\nIncorrect number of arguments\n");exit(1);} 
     if (access(argv[1],F_OK) != -1) 
     { 
       fd = open(argv[1],O_RDWR); 

       if (fd == -1) 
       { 
         perror("open"); 
         exit(1); 
       } 
       if(fstat(fd, &mystat)<0) 
       { 
         perror("fstat"); 
         close(fd); 
         exit(1); 
       } 
       p = mmap(0,mystat.st_size , PROT_READ | PROT_WRITE, 
         MAP_SHARED ,fd,0); 
       if(p == MAP_FAILED) 
       { 
         perror("mmap"); 
         close(fd); 
         exit(1); 
       } 
while(1) 
     { 
     printf("1.Insert\n"); 
     printf("2.Delete\n"); 
     printf("3.Lookup\n"); 
     printf("4.Print\n"); 
     printf("5.Quit\n"); 
     printf("Enter your choice : "); 

     scanf("%d",&choice); 
     switch(choice) 
     { 
     case 1: 
      printf("Enter the value to be inserted : "); 
      scanf("%d", &info); 
       //write(fd,&info,36); 
      if((root = insert(root,info)) == 0){} 
     else 

      break; 
     case 2: 
       printf("Enter the value you want to delete : "); 
       scanf("%d",&info); 
       root = deleteNode(root,info); 
       break; 
     case 4: 
       printtree(root,0); 
       break; 
       //printf("%s",arr[0]); 
       printf("\n"); 
      break; 
     case 5: 
       close(fd); 
      exit(1); 
     case 3: 
       printf("Enter the element you want to look for : "); 
       scanf("%d",&info); 
       Search(root,info); 
       break; 
     case 6: 
       printtree(root,0); 
       break; 
    default: 
    printf("Wrong choice\n"); 
     } 
     } 
} 
+1

Sooo ...有什麼問題?如何重現它? – Kamiccolo

+0

我應該如何將printtree函數寫入文件?我需要用mmap寫什麼嗎? –

+0

目前還不清楚你在問什麼。您是試圖存儲樹還是將其內容打印到文件中? –

回答

0

基本上,你映射了初始化看起來不錯(即,呼叫到mmap)。您只需確保映射文件足夠大,可能會在您致電mmap之前擴展它。查看my answer here以獲取有關如何確保內存映射文件足夠大的附加信息。

您需要做的下一步是通過向您寫入內存映射文件來替換函數printtree中的printf調用。

爲此,您可以將文件的內存映射傳遞給您的函數,類似於以下示例代碼。它使用指針算法處理類似於char[]的內存映射文件:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <sys/mman.h> 

typedef struct Node { 
    int key; 
    struct Node* left; 
    struct Node* right; 
} Node; 

void printtree(Node* root, int indent, char** mapped_file) {  
    if(root != NULL) { 
     printtree(root->left, indent + 1, mapped_file); 

     int i; 
     for(i = 0; i < indent; i++) { 
      **mapped_file = '\t'; 
      (*mapped_file)++; 
     } 
     char str[16]; 
     sprintf(str, "%d\n", root->key); 
     memcpy(*mapped_file, str, strlen(str)); 
     *mapped_file+=strlen(str); 

     printtree(root->right, indent + 1, mapped_file); 
    } 
} 

void main(int argc, const char* argv[]) { 
    Node* root = (Node*) malloc(sizeof(Node)); 

    root->key = 1; 
    root->left = (Node*) malloc(sizeof(Node)); 
    root->left->key = 2, 
    root->left->left = NULL; 
    root->left->right = NULL; 
    root->right = (Node*) malloc(sizeof(Node)); 
    root->right->key = 3; 
    root->right->left = (Node*) malloc(sizeof(Node)); 
    root->right->left->key = 4; 
    root->right->left->left = NULL; 
    root->right->left->right = NULL; 
    root->right->right = NULL; 

    printf("%s\n", argv[1]); 
    int fd = open(argv[1], O_RDWR); 

    if (fd == -1) { 
     perror("open"); 
     exit(1); 
    } 

    struct stat mystat; 
    if(fstat(fd, &mystat) < 0) { 
     perror("fstat"); 
     close(fd); 
     exit(1); 
    } 

    char* mapped_file = (char*) mmap(0, mystat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
    if(mapped_file == MAP_FAILED) { 
     perror("mmap"); 
     close(fd); 
     exit(1); 
    } 

    printtree(root, 0, &mapped_file); 
}