0

I am following the C programming tutorial at http://www.cprogramming.com/tutorial/c/lesson10.html. This particular tutorial teaches file I/O in C; in particular, the fopen command is discussed. At one point, they give the following example (which I think should print the contents of file test.txt):

FILE *fp;
fp=fopen("c:\\test.txt", "w");
fprintf(fp, "Testing...\n");

So, I made a text file called test.txt and saved it in my current, working directory (C:\cygwin\home\Andrew\cprogramming). Then I created a c file in this same directory, and it contains the following code:

#include <stdio.h>

int main()
{
  FILE *fp;
  fp=open("test.txt","w");
  fprintf(fp,"Testing...\n");
}

When I compile this c file (which I've called helloworld2.c) using gcc, I get the following messages:

helloworld2.c: In function `main':
helloworld2.c:40: warning: assignment makes pointer from integer without a cast

Then when I try to run the executable, I get:

Segmentation fault (core dumped)

Do you have any ideas about what I should try next?

Thank you very much for your time.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
Andrew
  • 1,499
  • 9
  • 25
  • 37
  • Your snippet writes "Testing..." to the file, overwriting whatever it had in it. – zneak Jun 11 '11 at 20:11
  • 1
    Did you know that forward slashes work on all OS including windows while backslashes only work on windows and need to be escaped? So: -2 for backslashes, +1 for forward slashes --> use forward slashes in your hardcoded paths. – ThiefMaster Jun 11 '11 at 20:12

3 Answers3

6

This is because you use open instead of fopen. Open is from the POSIX standard and returns an (integer) handle; fopen returns the memory address of a FILE structure. You cannot use both in an interchangeable way. As it stands, your code implicitly casts the received integer (likely 4) to a FILE* pointer, making it point to the memory address 4. This segfaults your program when fprintf attempts to access it.

fopen is cross-platform, but open is POSIX-only. You may want to stick to fopen for now.

zneak
  • 134,922
  • 42
  • 253
  • 328
3

fopen() returns a pointer to a FILE object while open() returns a file descriptor which is a plain int.
Unless you need low-level functions it's usually better to work with fopen and FILE objects.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
2

I'm guessing this was just an unfortunate typo - open() instead of fopen() - which just happens to work well enough to build a final executable (rather than a deliberate attempt to use open())...

You see warning: assignment makes pointer from integer without a cast because there is no "prototype" - a declaration of the argument and return types - for open() in <stdio.h>.

In the absence of such a prototype, the compiler assumes that such a function exists and returns an int, which your code assigns to the pointer variable fp.

It does in fact link successfully because there is a function called open() in the C library, but it does something different (as others have mentioned). But if (for example) you'd written fpen() instead, things would have gone more obviously wrong - it would have failed at the link stage, as there is no library function of that name.

If you compile with more warnings enabled - e.g. -Wall for GCC - you'll get some more helpful errors:

$ 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
$ 

The warning: implicit declaration of function 'open' tells you that there is a mismatch between the headers you've included, and the function you're trying to use.

Matthew Slattery
  • 45,290
  • 8
  • 103
  • 119