2015-08-08 64 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