我正在http://www.cprogramming.com/tutorial/c/lesson10.html关注C编程教程。这个特殊的教程用C语言教文件I / O;特别是,讨论了fopen命令。有一次,他们给出了以下示例(我认为应该打印文件test.txt的内容):
FILE *fp;
fp=fopen("c:\\test.txt", "w");
fprintf(fp, "Testing...\n");
所以,我创建了一个名为test.txt的文本文件,并将其保存在我当前的工作目录中(C:\ cygwin \ home \ Andrew \ cprogramming)。然后我在同一目录中创建了一个c文件,它包含以下代码:
#include <stdio.h>
int main()
{
FILE *fp;
fp=open("test.txt","w");
fprintf(fp,"Testing...\n");
}
当我使用gcc编译这个c文件(我称之为helloworld2.c)时,我收到以下消息:
helloworld2.c: In function `main':
helloworld2.c:40: warning: assignment makes pointer from integer without a cast
然后,当我尝试运行可执行文件时,我得到:
Segmentation fault (core dumped)
您对我接下来要尝试的内容有什么想法吗?
非常感谢你的时间。
答案 0 :(得分:6)
这是因为您使用的是open
而不是fopen
。 Open
来自POSIX标准并返回一个(整数)句柄; fopen
返回FILE
结构的内存地址。您不能以可互换的方式使用它们。就目前而言,您的代码隐式地将接收到的整数(可能为4)转换为FILE*
指针,使其指向内存地址4.当fprintf
尝试访问它时,会对程序进行段错误。
fopen
是跨平台的,但open
仅限POSIX。您现在可能想要坚持fopen
。
答案 1 :(得分:3)
fopen()
返回指向FILE
对象的指针,而open()
返回文件描述符int
。
除非您需要低级功能,否则通常最好使用fopen
和FILE
个对象。
答案 2 :(得分:2)
我猜这只是一个不幸的拼写错误 - open()
而不是fopen()
- 这恰好恰好可以构建最终的可执行文件(而不是故意尝试使用{{1} }})...
您看到open()
,因为warning: assignment makes pointer from integer without a cast
中的open()
没有“原型” - 参数和返回类型的声明。
如果没有这样的原型,编译器会假定存在这样的函数并返回<stdio.h>
,您的代码会将其分配给指针变量int
。
事实上它确实链接成功,因为是在C库中名为fp
的函数,但它做了不同的事情(正如其他人提到的那样)。但是,如果(例如)你写了open()
,那么事情会更明显错误 - 它会在链接阶段失败,因为没有该名称的库函数。
如果编译时启用了更多警告 - 例如GCC的fpen()
- 您会收到一些更有用的错误:
-Wall
$ gcc -Wall -o helloworld2 helloworld2.c
helloworld2.c: In function 'main':
helloworld2.c:6: warning: implicit declaration of function 'open'
helloworld2.c:6: warning: assignment makes pointer from integer without a cast
helloworld2.c:8: warning: control reaches end of non-void function
$
告诉您,您所包含的标头与您尝试使用的功能之间存在不匹配。