我想從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);
}
有的時候我不明白...你問一個問題,即使只有一條評論,它也會被拒絕投票。這是什麼交易? – user1610950
我沒有downvote,但我懷疑downvoter希望看到問題的最低限度的描述。請參閱[MCVE](http://stackoverflow.com/help/mcve) – user3386109
注意:我沒有dv。出於好奇,'static char * res_dir = NULL;'在你的** header **文件中?這在頭文件中沒有任何理由,還有一些爲什麼應該在* resource_utils.c *裏面聲明*。除此之外,你的代碼是相當字面上加載*的幻數,其中任何一個都可能導致根本問題。這應該通過valgrind徹底清洗。順便說一句。我希望你的* real *'getBasePath'不只是返回一個字符串文字。 free(base_path)指向動態分配,並在沒有它的情況下調用UB。 – WhozCraig