我正在制作练习程序,在学习C时对Makefile中的变量进行简单的更改。每当我运行此程序时,我都会遇到段错误,但我不知道为什么。我怀疑它与“r +”fopen模式或我对fseek()的使用有关。这是代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void rewind(FILE *f)
{
long start = 0;
fseek(f, start, SEEK_SET);
}
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("arguments too many or too few. use: setfile <filename> (minus .c extension)\n");
exit(1);
}
FILE *mfile = fopen("Makefile", "r+"); // note to self: r+ is for a file that already exists
FILE *old_mfile = fopen("OLD.Makefile", "r+"); // w+ erases the file and starts in read-write mode with a fresh one
char line[200];
char *fn_ptr;
char *name = argv[1];
while(fgets(line, 199, mfile)) // first create the backup
{
fputs(line , old_mfile); // before changing the line, write it to the backup
}
rewind(mfile); // reset the files to position 0
rewind(old_mfile);
puts("Makefile backed-up as 'OLD.Makefile'");
while(fgets(line, 199, old_mfile)) // now lets loop again and rewrite with the new FNAME
{
if((fn_ptr = (strstr(line, "FNAME= "))))
{
fn_ptr += strlen("FNAME= ");
int i;
for(i = 0; i < strlen(name); i++)
{
*(fn_ptr+i) = *(name+i);
}
*(fn_ptr+i) = '\0';
}
// printf("%s", line); // for debugging
fputs(line , mfile);
}
printf("FNAME is now: '%s'\n", argv[1]);
fclose(mfile);
fclose(old_mfile);
return 0;
}
答案 0 :(得分:3)
再次检查此行:
FILE *old_mfile = fopen("OLD.Makefile", "r+"); // w+ erases the file and starts in read-write mode with a fresh one
评论中有正确的模式,但fopen
来电时没有。
除了改变模式外,如何不发生分段错误?始终检查返回值!如果fopen
失败,则会返回NULL
。
答案 1 :(得分:1)
这是一个工作版本。这里有几个细微的要点,所以我将让你通过切换进出来逐一检查它们。如果仔细阅读,被调用函数的手册页就足够了。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void rewind(FILE *f)
{
long start = 0;
fseek(f, start, SEEK_SET);
}
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("arguments too many or too few. use: setfile <filename> (minus .c extension)\n");
exit(1);
}
FILE *mfile = fopen("Makefile", "r+"); // note to self: r+ is for a file that already exists
FILE *old_mfile = fopen("OLD.Makefile", "w+"); // w+ erases the file and starts in read-write mode with a fresh one
char line[200];
char *fn_ptr;
char *name = argv[1];
while(fgets(line, 199, mfile)) // first create the backup
{
fputs(line , old_mfile); // before changing the line, write it to the backup
memset(line,0x00,200);
}
rewind(mfile); // reset the files to position 0
rewind(old_mfile);
memset(line,0x00,200);
puts("Makefile backed-up as 'OLD.Makefile'");
fclose(mfile);
mfile = fopen("Makefile", "w");
while(fgets(line, 199, old_mfile)) // now lets loop again and rewrite with the new FNAME
{
if((fn_ptr = strstr(line, "FNAME=")) != NULL)
{
fn_ptr += strlen("FNAME=");
int i;
for(i = 0; i < strlen(name); i++)
{
*(fn_ptr+i) = *(name+i);
}
*(fn_ptr+i) = '\0';
}
// printf("%s", line); // for debugging
fputs(line , mfile);
fputs("\n" , mfile);
memset(line,0x00,200);
}
printf("FNAME is now: '%s'\n", argv[1]);
fclose(mfile);
fclose(old_mfile);
return 0;
}