我从fgets获得了细分,但有时只是。这是别人的代码,我不懂makefile,所以我用printf语句进行调试......我把它放在main函数的两个部分:(我只创建变量* f和line一次,但是我两次fopen和fclose文件。)
FILE *f = NULL;
char line[1000];
if ((f=fopen(filename,"r+"))==NULL)
{
printf("Error opening file\n");
f=0;//...handle error... //(usually just call abort() or return -1
}
//f = rfopen(fname, "r+");
printf("f from eval_args: %d, filename %s\n",f,filename);
printf("trying to read from file...\n");
printf("%s\n",fgets(line, sizeof (line), f));
printf("...succeeded\n");
fclose(f);
给了我两个不同的输出:
f from eval_args: 4609600, filename /correct/path/to/file
trying to read from file...
100
...succeeded
f prior to entering density profile: 4609600, filename /correct/path/to/file
trying to read from file...
Segmentation fault (core dumped)
我检查文件是否正确打开,并防止读取比'line'更多的字符。我在一个论坛中看到文件名长度不应超过49个字符...但是a)这是一个奇怪的限制,b)为什么它第一次起作用?
有谁知道我还能检查什么?
答案 0 :(得分:1)
如果不是很麻烦你可以,但猜猜你知道,做点什么;
可以美化一下,但是:
#include <stdio.h>
#include <stdarg.h>
#define MAX_LINE 1024
void dbg_fprnt(FILE *fh, char *fmt, ...)
{
char buf[MAX_LINE];
char inf[MAX_LINE] = {0};
va_list args;
if (fmt && *fmt) {
va_start(args, fmt);
va_end(args);
vsprintf(inf, fmt, args);
}
buf[0] = '\n';
buf[1] = '\0';
if (ferror(fh)) {
fprintf(stderr, " * ERR, ferror() --- \n");
} else if (fh == NULL) {
fprintf(stderr,
" * DBG PRNT ERR;; Trying to print from NULL ---\n");
/* else if (and so forth) */
} else {
if (fgets(buf, MAX_LINE, fh) == NULL) {
perror(" * ERR DBG PRNTF FGETS, --");
}
}
printf("%-15s FC:: %s", inf, buf);
}
int main(void)
{
char *fn = "lorem_ipsum";
FILE *fh;
if ((fh = fopen(fn, "r")) == NULL) {
fprintf(stderr,
"Unable to open '%s' for read.\n",
fn);
return 1;
}
setbuf(stdout, NULL);
dbg_fprnt(fh, "SOME LINE: %d", 123);
dbg_fprnt(fh, "%s", "SASA");
dbg_fprnt(fh, "");
dbg_fprnt(fh, NULL);
dbg_fprnt(fh, "%s %d !", "Woot", 33);
dbg_fprnt(fh, "@%d :::", __LINE__);
fclose(fh);
dbg_fprnt(fh, "@%d :::", __LINE__);
return 0;
}
示例输出:
./fe
SOME LINE: 123 FC:: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
SASA FC:: tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
FC:: quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
FC:: consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
Woot 33 ! FC:: cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
@52 ::: FC:: proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
* ERR DBG PRNTF FGETS, --: Bad file descriptor
@54 ::: FC::
答案 1 :(得分:0)
根据您的描述,可能的原因可能是第二个fgets
没有成功,因此返回NULL
,这会导致段错误。那么为什么第二个fgets
会失败?你可以看一下......
参考fgets
规范:
成功时,该函数返回相同的str参数。 如果遇到文件结尾且未读取任何字符,则str的内容保持不变,并返回空指针。 如果发生错误,则返回空指针。 使用ferror或feof检查是否发生错误或是否已达到文件结尾。 http://www.cplusplus.com/reference/clibrary/cstdio/fgets/
因此,通常直接使用fgets
的返回值不是一个好习惯。
答案 2 :(得分:0)
从你的打印出来:
f from eval_args: 4609600, filename /correct/path/to/file
trying to read from file...
100
...succeeded
f prior to entering density profile: 4609600, filename /correct/path/to/file
trying to read from file...
Segmentation fault (core dumped)
您在输入密度配置文件之前有“f”而不是“来自eval_args的f”,但在您提供的源中不存在“输入密度配置文件之前的f”,我认为您没有运行相同的代码。< / p>
并且对于注释“//...handle error ... //(通常只是调用abort()或返回-1”,没有代码可以处理它,所以它仍然可以下去并且coredump。< / p>
从fgets返回的描述:
成功完成后,fgets()将返回s。如果流位于文件末尾,则应设置流的文件结束指示符,并且fgets()应返回空指针。如果发生读错误,则应设置流的错误指示符,fgets()应返回空指针,并设置errno以指示错误。
所以EOF或其他任何不好的东西都会成为printf coredump。
我建议采取以下措施:
FILE *f = fopen(filename,"r+");
if (f) {
char line[1000];
printf("f from eval_args: %p, filename %s\n",f,filename);
printf("trying to read from file...\n");
while(fgets(line, sizeof (line), f)) printf("%s",line);
fclose(f);
}
else printf("Error opening file\n");