So I've written a small program to keep updating my dotfiles in another directory with a git repository. I just wanted to keep practising my C coding.
所以我写了一个小程序,用git存储库继续更新我的dotfiles在另一个目录中。我只是想继续练习我的C编码。
The program is a gross violation of the DRY principle and does not work either. Here is the code:
该计划严重违反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]);
}
}
}
Why do I get a segmentation fault ?! (Also anyway to keep it DRY?)
为什么我会出现分段错误? (还是为了让它干嘛?)
EDIT: You are all right. One of them was NULL. I just added an if statement before the while loop to check if the current file from either array is NULL.
编辑:你没事。其中一个是NULL。我只是在while循环之前添加了一个if语句来检查来自任一数组的当前文件是否为NULL。
NOW how can I make this DRY?
现在我该怎么做这个干?
2 个解决方案
#1
1
There are many possibilities in your code to get segfault. Since you are not checking any of the fopen(), one missing file will cause fgetc() to segfault. Same with fputc(). You can use ltrace to see exactly which library call caused the segfault.
您的代码有很多可能性来获取段错误。由于您没有检查任何fopen(),因此一个丢失的文件将导致fgetc()发生段错误。与fputc()相同。您可以使用ltrace来确切地查看哪个库调用导致了段错误。
#2
1
As other wrote, there're many possible reason for a SegFault.
Adding some error control will helps.
正如其他人写的那样,SegFault有很多可能的原因。添加一些错误控制将有所帮助。
Regarding how to make it DRY, this is a possibility:
关于如何使其干燥,这是一种可能性:
#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;
}
I've added some error control and the program keep working even if one of the file is missing.
我添加了一些错误控制,即使其中一个文件丢失,程序也会继续工作。
#1
1
There are many possibilities in your code to get segfault. Since you are not checking any of the fopen(), one missing file will cause fgetc() to segfault. Same with fputc(). You can use ltrace to see exactly which library call caused the segfault.
您的代码有很多可能性来获取段错误。由于您没有检查任何fopen(),因此一个丢失的文件将导致fgetc()发生段错误。与fputc()相同。您可以使用ltrace来确切地查看哪个库调用导致了段错误。
#2
1
As other wrote, there're many possible reason for a SegFault.
Adding some error control will helps.
正如其他人写的那样,SegFault有很多可能的原因。添加一些错误控制将有所帮助。
Regarding how to make it DRY, this is a possibility:
关于如何使其干燥,这是一种可能性:
#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;
}
I've added some error control and the program keep working even if one of the file is missing.
我添加了一些错误控制,即使其中一个文件丢失,程序也会继续工作。