2015-08-08 65 views
-1

我想從c程序中設置本地文件夾訪問權限,方法是首先將字符串初始化爲隨後從該處讀取文件的位置。我還需要最終以類似的方式編寫文件,但我收到了一些奇怪的錯誤。c字符串和文件操作

第一代碼: resource_utils.h

static char* res_dir = NULL; 

void clearnUpResourcePath(void); 
char* getResource(char* filename); 
char* readFile(char* file_path); 
void writeFile(filename, File* file); 

resource_utils.c

#include "resource_utils.h" 

static char* getBasePath(void); 
static void initResourcePath(void); 

char* getResource(char* filename) 
{ 
    if(res_dir == NULL) 
    { 
     initResourcePath(); 
    } 
     printf("res dir: %s || fn:%s\n",res_dir, filename); 
     char* str = (char*)malloc(sizeof(char) + strlen(res_dir) + strlen(filename)); 
     memcpy(str, res_dir, strlen(res_dir)+1); 
     memcpy(str + strlen(res_dir), filename, strlen(filename)); 
     str[(strlen(filename) + strlen(res_dir))] = '\0'; 
     printf("resource filename:%s\n\n",str); 
     return str; 
} 

static void initResourcePath(void) { 
    char *base_path = getBasePath(); 

    size_t len = strlen(base_path) + 22; 
    size_t i = 0; 
    size_t sz = 0; 
    char tmp[len]; 
    while(base_path[i] != '\0') 
    { 
     if(base_path[i] == 'b' && base_path[i+1] == 'i' && base_path[i+2] == 'n') 
     { 
      sz = i; 
     } 
     tmp[i] = base_path[i]; 
     i++; 
    } 
    char* b = strstr(tmp, "/bin"); 
    memcpy(b, "/bin/resources/",15); 
    tmp[ sz + 14 ] = '\0'; 

    res_dir = (char*)malloc(sizeof(char) * (sz + 4)); 
    i = 0; 
    while(tmp[i] != '\0') 
    { 
     res_dir[i] = tmp[i]; 
     i++; 
    } 
    res_dir[i] = '\0'; 

    free(base_path); 

} 

void clearnUpResourcePath(void) 
{ 
    free(res_dir); 
} 

static char* getBasePath(void) 
{ 
    return "string to working directory" 
} 

char* readFile(char* file_path) 
{ 
    FILE* fp = fopen(file_path, "r"); 
    if(fp == NULL) 
    { 
     perror("Error while opening the file.\n"); 
     printf("failed to open file path:%s\n",file_path); 
     exit(EXIT_FAILURE); 
    } 
    size_t size = 1024; 
    char ch; 
    int index = 0; 
    char* line = (char*)malloc(sizeof(char) * size); 
    while((ch = (char)fgetc(fp)) != EOF) 
    { 
     *(line+index) = ch; 
     ++index; 
     if(index == size-1) 
     { 
      size = size * 2; 
      line = realloc(line, size); 
      printf("\nreallocing %zu\n",size); 
     } 
     line = realloc(line, (sizeof(char) * index) + 1); 
     *(line+index) = '\0'; 
    } 
    //printf("sanity check\n\n%d\n\n",strlen(line)); 
    //printf("final size: %lu for loading: %s\n",strlen(line), file_path); 
    fclose(fp); 
    return line; 
} 

這基本上是想設置此資源路徑一次,把它周圍的程序的生命週期和在程序退出之前釋放它,但有時會得到一些奇怪的結果。

看看這個輸出

char* vshad = getResource("vert.shad"); 
    char* fshad = getResource("frag.shad"); 
    char* name = getResource("pal.ppm"); 
    char* name1 = getResource("1234pal.ppm"); 
    char* name2 = getResource("pal.ppm1234"); 
    char* name3 = getResource("pal1.ppm"); 
    char* name4 = getResource("pal.pp"); 
    char* name5 = getResource("pal.ppdddddm"); 
    char* name6 = getResource("pa"); 

res dir: /Users/username/DIRECTORY/project/build/bin/resources/ || fn:vert.shad 
res dir len:48, filename len:9 
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/vert.shad 

res dir: /Users/username/DIRECTORY/project/build/bin/resources/ || fn:frag.shad 
res dir len:48, filename len:9 
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/frag.shad 

res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:pal.ppm 
res dir len:57, filename len:7 
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpal.ppm 

res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:1234pal.ppm 
res dir len:57, filename len:11 
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS1234pal.ppm 

res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:pal.ppm1234 
res dir len:57, filename len:11 
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpal.ppm1234 

res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:pal1.ppm 
res dir len:57, filename len:8 
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpal1.ppm 

res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:pal.pp 
res dir len:57, filename len:6 
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpal.pp 

res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:pal.ppdddddm 
res dir len:57, filename len:12 
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpal.ppdddddm 

res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:pa 
res dir len:57, filename len:2 
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpa 

loaded name:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpal.ppm? 

前兩個電話負荷正常,但後續調用,尤其是如果我更改文件名的長度導致代碼以打破。我不太確定。

我還注意到我的res_dir的長度發生了變化,我真的不明白。

與接受的答案一起,這是我的新代碼W/O幻數

static void initResourcePath(void) 
{ 
    char *base_path = getBasePath(); 

    size_t len = strlen(base_path) *2; //making enough space 
    size_t i, sz = 0; 
    char tmp[len]; 
    while(base_path[i] != '\0') 
    { 
     if(base_path[i] == 'b' && base_path[i+1] == 'i' && base_path[i+2] == 'n') 
     { 
      sz = i; 
     } 
     tmp[i] = base_path[i]; 
     i++; 
    } 
    char* b = strstr(tmp, "/bin"); 
    memcpy(b, "/bin/resources/",15); 
    tmp[ sz + 14 ] = '\0'; 
    res_dir = (char*)malloc(sizeof(char) * (strlen(tmp) +1)); 
    strcpy(res_dir, tmp); 
    free(base_path); 
} 
+1

有的時候我不明白...你問一個問題,即使只有一條評論,它也會被拒絕投票。這是什麼交易? – user1610950

+0

我沒有downvote,但我懷疑downvoter希望看到問題的最低限度的描述。請參閱[MCVE](http://stackoverflow.com/help/mcve) – user3386109

+0

注意:我沒有dv。出於好奇,'static char * res_dir = NULL;'在你的** header **文件中?這在頭文件中沒有任何理由,還有一些爲什麼應該在* resource_utils.c *裏面聲明*。除此之外,你的代碼是相當字面上加載*的幻數,其中任何一個都可能導致根本問題。這應該通過valgrind徹底清洗。順便說一句。我希望你的* real *'getBasePath'不只是返回一個字符串文字。 free(base_path)指向動態分配,並在沒有它的情況下調用UB。 – WhozCraig

回答

1

您遇到的問題是在這裏:

res_dir = (char*)malloc(sizeof(char) * (sz + 4)); 

你不分配足夠的空間。您可能打算使用sz + 14而不是sz + 4。這是WhozCraig提到的使用幻數的問題之一。

,而不是做一些令人費解這樣,你知道你複製tmpres_dir,所以做這個:

res_dir = malloc(strlen(tmp)+1); 

注意的malloc返回值不被鑄造。這樣做在C中可以隱藏微妙的錯誤,如果你不能#include <stdlib.h>

+0

謝謝,我實際上通過使用strcpy清理了很多代碼。我會在這個問題上加上這一點。 – user1610950