2015-08-08 2 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, которые я действительно не понимаю.

вместе с общепринятом ответ, вот мой новый код без магических чисел

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

Я не спускал вниз, но я подозреваю, что downvoter хотел бы увидеть минимальное описание проблемы. См. [MCVE] (http://stackoverflow.com/help/mcve) – user3386109

+0

Примечание: я не сделал этого. Из любопытства, 'static char * res_dir = NULL;' в вашем ** header ** файле? Это не имеет оснований для того, чтобы быть в заголовке, и несколько для того, почему он должен быть объявлен * внутри * resource_utils.c * only *. Помимо этого, ваш код в буквальном смысле * загружается * магическими числами, любой из которых может способствовать возникновению проблемы с корнем. Это заслуживает тщательной стирки через valgrind. Btw. Надеюсь, ваш * real * 'getBasePath' больше, чем возвращает строковый литерал. Этот 'free (base_path)' рассчитывает на динамическое распределение и вызывает UB без него. – WhozCraig

ответ

1

Проблема у Вас есть здесь:

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

Вы не выделять достаточно места. Вероятно, вы использовали sz + 14 вместо sz + 4. Это одна из проблем с использованием магических чисел, о которых упомянул WhozCraig.

Вместо того, чтобы делать что-то, свернутый так, вы знаете, что вы копируете tmp в res_dir, так что вместо этого:

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

Обратите внимание, что возвращаемое значение malloc не будучи с приведением. Выполнение этого в C может скрыть тонкие ошибки, если вы не достигли #include <stdlib.h>.

+0

спасибо, и я на самом деле очистил много кода, используя strcpy. Я добавлю это к вопросу. – user1610950

Смежные вопросы