C 中奇怪的段错误
好吧,所以我不太确定这里发生了什么。我有一个简单的函数 int foo(char *filename)
,它接受 filename
并计算文件中的单词数。
int foo(char *filename){
FILE *inFile;
int wordCount = 0;
printf("foo\n"); // test printf() statement (currently prints)
char word[50];
inFile = (&filename, "r");
printf("infile\n"); // test printf() statement (currently prints)
while (1){
printf("while"); // test printf() statement (doesn't print)
fscanf(inFile, "%s", word);
if (feof(inFile))
break;
printf("%d", wordCount); //test printf() statement
wordCount++;
}
fclose(inFile);
return wordCount;
}
如您所见,我打印“infile”,但不打印“while”。我遇到分段错误。有谁知道为什么这不起作用另外,我的 inFile = (&filename, "r");
语句正确吗?我不太擅长指点。
Ok, so I'm not really sure what is going on here. I have a simple function, int foo(char *filename)
, that takes filename
and counts the words in a file.
int foo(char *filename){
FILE *inFile;
int wordCount = 0;
printf("foo\n"); // test printf() statement (currently prints)
char word[50];
inFile = (&filename, "r");
printf("infile\n"); // test printf() statement (currently prints)
while (1){
printf("while"); // test printf() statement (doesn't print)
fscanf(inFile, "%s", word);
if (feof(inFile))
break;
printf("%d", wordCount); //test printf() statement
wordCount++;
}
fclose(inFile);
return wordCount;
}
As you can see, I print "infile", but not "while". I get a segmentation fault. Does anyone have any idea why this doesn't work Also, is my inFile = (&filename, "r");
statement correct? I'm not that great with pointers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我很惊讶这一行实际上可以编译:
如果您尝试打开一个文件:
编辑:
如上所述,您需要以
\n
结束您的printf
或调用 fflush(stdout) ,否则它将被缓冲而不打印。I'm surprised this line actually compiles:
If you're trying to open a file:
EDIT:
And as mentioned, you need to end your
printf
s with\n
or callfflush(stdout)
or it will get buffered and not print.您希望这条线做什么?
因为看起来您错过了功能调用。我怀疑你想要这样的东西:
也就是说,fopen函数需要一个字符指针,而你有这个:
所以你不需要使用
&
运算符。&
运算符返回变量的地址,因此通过输入&filename
您最终会得到 (指向 (char) 的指针)。您很少会在字符串中使用&
运算符;当函数需要返回多个值时(例如 Unixwait()
函数),您通常会看到它。 。有许多关于 C 指针的教程 更详细地说;Google 搜索“c 指针”会产生一些可能的结果,当然,请阅读您的 K&R :)。
What are you expecting this line to do?
Because it looks like you're missing a functional call. I suspect you wanted something like this:
That is, the
fopen
function expects a character pointer, and you have this:So you don't need to use the
&
operator. The&
operator returns the address of a variable, so by entering&filename
you're ending up with (a pointer to (a pointer to (char)). You'll rarely use the&
operator with strings; you'll usually see it used when a function needs to return multiple values (like the Unixwait()
function).There are a number of tutorials out there that talk about C pointers in more detail; a Google search for "c pointers" yields some likely results. And of course, read your K&R :).
您看不到“while”打印的原因是因为它没有以
\n
终止,因此在发生段错误时保留在缓冲区中并且没有打印出来。段错误发生在
fscanf
处,因为您错过了fopen
,并且弄乱了指针。 @Mystical 解释了如何修复它。The reason you don't see the "while" print is because it's not terminated with
\n
, thus is kept in the buffer and not printed out, by the time the seg fault occurs.The seg fault occurs at
fscanf
, because you missed thefopen
, and messed up your pointers. @Mystical explained how to fix it.始终检查
fopen()
的返回值,对它的调用似乎丢失了。请注意,在调用
fopen()
时,filename
中缺少&
;你根本不需要它。fscanf()
之前的printf()
不会产生任何结果,因为输出字符串不以换行符结尾;它会一直保留到您打印换行符为止,并且崩溃发生在您执行此操作之前。发生崩溃的原因是字符串“r”不是有效的文件流;如果您实际上调用了
fopen()
,则可能是因为打开失败并且您没有检查它。如果您的编译器没有向您发出有关代码的警告,请获取更好的编译器。如果它确实向您发出警告,请在发布到 StackOverflow 之前学会注意它们(并修复它们)。
当您这样做时,您可能需要考虑如果您要阅读的单词达到 50 个字符或更长,会发生什么情况。幸福不会随之而来。您应该考虑使用:
如果一个单词长于 49 个字符,它至少现在会被分割成一定数量的 49 字节单元(每个单元都算作一个单词),而不会出现缓冲区溢出问题(崩溃的另一个来源)。如果您需要循环中的诊断打印,那就这样吧;添加大括号并打印。
在我(超过 25 年)的编程生涯中,我很少有理由使用
feof()
。使用它的代码通常是可疑的;我想知道这个人是否在学习 C 时学会了 Pascal 并且没有忘记它。ALWAYS check the return value from
fopen()
, the call to which seems to be missing.Note the absence of the
&
fromfilename
in the call tofopen()
; you simply don't need it.The
printf()
before thefscanf()
does not produce anything because the output string does not end with a newline; it is held over until you do print a newline, and the crash occurs before you do that.The crash occurs because the string
"r"
is not a valid file stream; if you'd actually calledfopen()
, it would probably be because the open failed and you did not check it.If your compiler did not give you warnings about the code, get a better compiler. If it did give you warnings, learn to heed them (and fix them) before posting to StackOverflow.
While you're at it, you might want to consider what happens if the word you get to read is 50 characters or longer. Happiness does not ensue. You should consider using:
If a word is longer than 49 characters, it will at least now be split up into some number of 49-byte units (each counted as a word) without giving you buffer overflow problems (another source of crashes). If you need a diagnostic print in the loop, so be it; add the braces and print.
I have very, very seldom had cause to use
feof()
in my (25+ year) programming career. Code using it is generally suspect; I wonder if the person learned Pascal and hasn't unlearned it when learning C.