2016-01-30 5 views
0

Итак, я написал небольшую программу для обновления моих дотфайлов в другом каталоге с репозиторием git. Я просто хотел продолжить практику программирования на C.C программа для резервного копирования файлов точек

Программа является грубым нарушением принципа DRY и не работает. Вот код:

#include <stdio.h> 


int main(void) 
{ 
    FILE *files_from[7]; 
    files_from[0] = fopen(".vimrc", "r"); 
    files_from[1] = fopen(".profile", "r"); 
    files_from[2] = fopen(".tmux_conf", "r"); 
    files_from[3] = fopen(".zshrc", "r"); 
    files_from[4] = fopen(".bashrc", "r"); 
    files_from[5] = fopen(".bash_aliases", "r"); 
    files_from[6] = fopen(".gitconfig", "r"); 

    FILE *files_to[7]; 
    files_to[0] = fopen("dotFiles/.vimrc", "w"); 
    files_to[1] = fopen("dotFiles/.profile", "w"); 
    files_to[2] = fopen("dotFiles/.tmux.conf", "w"); 
    files_to[3] = fopen("dotFiles/.zshrc", "w"); 
    files_to[4] = fopen("dotFiles/.bashrc", "w"); 
    files_to[5] = fopen("dotFiles/.bash_aliases", "w"); 
    files_to[6] = fopen("dotFiles/.gitconfig", "w"); 


    for(int i = 0; i < 7; ++i) 
    { 
     int character; 
     while((character = fgetc(files_from[i])) != EOF) 
     { 
      fputc(character, files_to[i]); 
     } 
    } 



} 

Почему я получаю ошибку сегментации?! (Также в любом случае держать его сухим?)

EDIT: С вами все в порядке. Один из них был NULL. Я просто добавил оператор if перед циклом while, чтобы проверить, является ли текущий файл из любого массива NULL.

ТЕПЕРЬ Как я могу сделать это СУХОЙ?

+1

Запуск в отладчике, чтобы поймать сбой в действии. –

+3

вы не проверяете, являются ли files_from [i] или files_to [i] NULL перед их использованием. Может быть, один из них NULL, и он падает при доступе к нему. – phoenix

+2

Это может быть NULL, если есть некоторая ошибка при открытии файла – phoenix

ответ

1

В коде есть много возможностей для получения segfault. Поскольку вы не проверяете какой-либо из fopen(), один отсутствующий файл вызывает fgetc() для segfault. То же самое с fputc(). Вы можете использовать ltrace, чтобы увидеть, какой именно вызов библиотеки вызвал segfault.

1

Как писал другой, существует много возможных причин для SegFault.
Помогает добавить некоторый контроль ошибок.

касается того, как сделать это DRY, это возможность:

#include <stdio.h> 
#include <string.h> 
#include <errno.h> 

#define MAX_PATH (50) 
#define dim(x) (sizeof(x)/sizeof(x[0])) 


static const char sFiles[][MAX_PATH] = { 
    ".vimrc", 
    ".profile", 
    ".tmux_conf", 
    ".zshrc", 
    ".bashrc", 
    ".bash_aliases", 
    ".gitconfig", 
}; 
static const char sDestDir[] = {"dotFiles/"}; 



int main(void) 
{ 
    long num = dim(sFiles); 
    printf("Size: %lu \n", num); 
    FILE *files_from; 
    FILE *files_to; 
    char destPath[MAX_PATH]; 
    int character; 
    int s = 0; 

    for (int i=0; i<num; i++) { 
    errno = 0; 
    printf("loop: %d\n",i); 
    strncpy(destPath, sDestDir, MAX_PATH); 
    files_from = fopen(sFiles[i], "r"); 
    if (files_from == NULL) { 
     fprintf(stderr, "File %s open failed: %s\n", sFiles[i], strerror(errno)); 
     continue; 
    } 
    strncat(destPath, sFiles[i], MAX_PATH); 
    files_to = fopen(destPath, "w"); 
    if (files_to == NULL) { 
     fprintf(stderr, "File %s open failed: %s\n", destPath, strerror(errno)); 
     s = 0; 
     s = fclose(files_from); 
     if (EOF == s) { 
     perror("Close Failed"); 
     } 
     continue; 
    } 
    printf("Now Copying %s to %s\n", sFiles[i], destPath); 
    while((character = fgetc(files_from)) != EOF) { 
     fputc(character, files_to); 
    } 
    s = 0; 
    s = fclose(files_to); 
    if (EOF == s) { 
     perror("Close Failed"); 
    } 
    s = 0; 
    s = fclose(files_from); 
    if (EOF == s) { 
     perror("Close Failed"); 
    } 
    } 

    return 0; 
} 

Я добавил некоторый контроль ошибок и программы продолжают работать, даже если один из файла отсутствует.

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