Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

ojb13004

macrumors newbie
Original poster
Nov 26, 2013
4
0
Code:
#include <stdio.h>
int main() {
    FILE *inf;
    float myData;
    inf=fopen("Users/oliverburns/Documents/Document1.txt","r");
    fscanf(inf,"%f",&myData);
    printf("Read from file: myData=%f\n",myData);
         
           fclose(inf);
           return(0); }

I'm an engineering student who needs to be able to program on my Mac. I can get the basic functions of C to work but the function 'fopen()' doesn't seem to work. File access is very fundamental to what I need to do. This is the output I get for the above code when I run it;

(lldb)


Can anyone tell me where I am going wrong? The file exists and there is text in it.


Thanks in advance.

#confused
 
Last edited by a moderator:
Looks like you're just missing a leading slash from the file name.

Code:
inf=fopen("[COLOR="Red"][B]/[/B][/COLOR]Users/oliverburns/Documents/Document1.txt","r");

Are you adapting code from Windows and removed a "C:\"

B
 
See screenshot attached, this is what I get. I haven't converted it from Windows so that shouldn't be the problem.

Thanks.
 

Attachments

  • Screen Shot 2013-11-26 at 15.44.46.png
    Screen Shot 2013-11-26 at 15.44.46.png
    354.5 KB · Views: 171
See screenshot attached, this is what I get. I haven't converted it from Windows so that shouldn't be the problem.

Thanks.

You need to check whether inf == NULL. That's what's going to happen if the file couldn't be opened, and then fread will crash.

And you just _might_ have got a warning from the compiler telling you that passing myData to fread isn't a good idea. Can you figure out yourself why that is?
 
Several things could still be wrong.

As gnasher said, checking for success in fopen is always a good idea.

Code:
include <stdio.h>
int main() {
FILE *inf;
float myData;

inf=fopen("./Document1.txt","r");
if (NULL != inf) {	
	fscanf(inf,"%f",&myData);
	printf("Read from file: myData=%f\n",myData);
	fclose(inf);
else
	printf("Could not open file \n\r");

return(0); }

Works fine for me for most contents of ./Document1.txt (in the same folder), but if the file you are looking for does not exist or you don't have permissions to it, it will bomb.

Please note that Unix filenames are case sensitive. document1.txt is not the same as Document1.TXT.

B
 
See screenshot attached, this is what I get. I haven't converted it from Windows so that shouldn't be the problem.

Thanks.

The only way you are going to get that error is if 'inf' is NULL, which it will be if the file doesn't exist at the given path or failed to open for some other reason.

You need to check if 'inf' is NULL before attempting to use it, you can use perror which will print the reason for it not opening, then abort like this for example.

Code:
    inf = fopen(path, "r");
    if(inf == NULL) {
        perror(path);
        return 1;
    }

Please note that Unix filenames are case sensitive. document1.txt is not the same as Document1.TXT.

That would depend on the file system, in case of HFS+ case insensitive should be the default.
 
Product -> Scheme -> Edit Scheme

Left list, select "Run"

Right list, "Working Directory" check "Using custom working directoy" and then select your working directy

"OK"

Run/Debug your program.
 
In addition to a check for fopen() returning NULL, you must also check that fscanf() returns 1 here.

If a float value isn't converted by fscanf(), then the myData variable is uninitialized, and attempts to print it can fail. The returned value from fscanf() tells you how many items were actually converted, or EOF if the input has been exhausted.

https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/fscanf.3.html

RETURN VALUES
These functions return the number of input items assigned. This can be fewer than provided for, or
even zero, in the event of a matching failure. Zero indicates that, although there was input available,
no conversions were assigned; typically this is due to an invalid input character, such as an
alphabetic character for a `%d' conversion. The value EOF is returned if an input failure occurs
before any conversion such as an end-of-file occurs. If an error or end-of-file occurs after conversion
has begun, the number of conversions which were successfully completed is returned.


To find out what's actually in your input file, open a Terminal window, then copy and paste this line into it:
Code:
hexdump -C /Users/oliverburns/Documents/Document1.txt | head -n 5
Then copy and paste the complete output and post it here.
If an error message is produced, copy and paste that in its entirety.

It's possible that the file exists and is named "Document1.txt", but it's not actually a plain text file. This would almost certainly cause fscanf() to fail its conversion.


Finally, if you're following a tutorial or book, please tell us exactly which one. That is, the URL of an online tutorial, or the title, author and edition of a book.

If you're not following a tutorial, you probably should be, because the posted code shows a lot of mistakes that a decent step-by-step tutorial will cover.

If might also help to tell us exactly which engineering field you're a student in.
 
To find out what's actually in your input file, open a Terminal window, then copy and paste this line into it:
Code:
hexdump -C /Users/oliverburns/Documents/Document1.txt | head -n 5
Then copy and paste the complete output and post it here.
If an error message is produced, copy and paste that in its entirety.

It's possible that the file exists and is named "Document1.txt", but it's not actually a plain text file. This would almost certainly cause fscanf() to fail its conversion.

Interesting. I took the code I posted earlier and tried to reproduce the failure you expected here and didn't see it.

I got:

Code:
$ rm Document1.txt 
[B]$ ./test [/B]
Could not open file 
[B]$ dd if=/dev/random of=./Document1.txt bs=1024b count=1
[/B]1+0 records in
1+0 records out
524288 bytes transferred in 0.051044 secs (10271298 bytes/sec)
[B]$ hexdump -C ./Document1.txt | head -n 5 [/B]
00000000  4e 15 97 fc d0 de ba dc  db 12 a8 1e 29 33 5d b8  |N...........)3].|
00000010  8b 89 6c 41 9c 21 d6 ee  2b b4 aa 2f b1 ff 8e 55  |..lA.!..+../...U|
00000020  3f 70 a8 d9 4c 77 27 45  1a 5b 5f ce 22 22 b0 bb  |?p..Lw'E.[_.""..|
00000030  99 2a 39 a6 13 d0 c0 93  4b 3c 74 41 9a 30 ec a4  |.*9.....K<tA.0..|
00000040  24 ef 68 0e eb b9 3c e4  df ea df f3 48 1e 09 d5  |$.h...<.....H...|
[B]$ ./test [/B]
Read from file: myData=0.000000
[B]$ mv Document1.txt document1.TxT
$ ./test 
[/B]Read from file: myData=0.000000

Of course, if I modify the code to check the return from fscanf, it tells me it could not read a float from the file.

EDIT: Oh, and I confirmed that by default it's case insensitive. Old habits die hard.

B
 
Last edited:
Interesting. I took the code I posted earlier and tried to reproduce the failure you expected here and didn't see it.
...
Of course, if I modify the code to check the return from fscanf, it tells me it could not read a float from the file.

If I recall correctly, when fscanf() fails a conversion, the referenced storage area (&myData) is not written to at all. Since the float in question (myData) is uninitialized, then its value after fscanf() doesn't convert is undetermined. It's possible that the undetermined bit-pattern is a valid float representation. It's also possible the value is an invalid float representation. There's really no way to predict what the value will be, nor how printf will handle it.

So it's not that I expected a failure, it's that the potentially undetermined value of myData may or may not cause a failure. There's no way to predict what will happen.
 
There's really no way to predict what the value will be, nor how printf will handle it.

Pretty sure printf will print all of them but for reserved float values produces 'nan' or 'inf'.

----------

EDIT: Oh, and I confirmed that by default it's case insensitive. Old habits die hard.

B

It may be a good advice to follow anyway, that way it should work on case sensitive filesystems as well. Probably nothing to worry about here though.
 
So it's not that I expected a failure, it's that the potentially undetermined value of myData may or may not cause a failure. There's no way to predict what will happen.

Yeah, I think there must be an implicit
Code:
float myData=0;
in there somehow. I put that in explicitly in the version I did with checking scanf's output.

Note that I'm using the command line tools and not Xcode.

It may be a good advice to follow anyway, that way it should work on case sensitive filesystems as well. Probably nothing to worry about here though.

Yeah, I only brought it up as I didn't know where the OP was going with this.

I ran into this on an embedded Linux project I was working on last year where some Windows code we were porting was using two distinct case sensitive files because the person we inherited the code from assumed case insensitivity.

B
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.