469,592 Members | 2,038 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,592 developers. It's quick & easy.

How do I check if a file is empty in C??

Hi group..I am writing a playlist management protocol where I have a
file that holds all the playlists and a file that holds all the
songs....before a playlist is created I need to check to see if the
playlist file is empty so that I can assign an integer value to a
playlist id field if it is the first playlist being written to the
file....can anyone help?? Thanks in advance

wetherbean

Nov 14 '05 #1
19 30279
Nevermind, someone just gave me an idea that I think will work
fine...he said to fseek tot he end of the file and then do an ftell and
if it is 0 then the file is empty

Nov 14 '05 #2
In article <11*********************@o13g2000cwo.googlegroups. com>
wetherbean <bj******@gmail.com> wrote:
Hi group..I am writing a playlist management protocol where I have a
file that holds all the playlists and a file that holds all the
songs....before a playlist is created I need to check to see if the
playlist file is empty so that I can assign an integer value to a
playlist id field if it is the first playlist being written to the
file....can anyone help?? Thanks in advance


Definition: a file is "empty" if you cannot read anything from it.
(Is there a potential flaw in this definition? [I say yes, but
this is an exercise; you are supposed to identify potential flaws,
not just answer "yes" or "no". :-) ])

Conclusion: open the file and try to read from it. If you get
some data, it is not empty. If you get EOF immediately, it is
empty.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #3
wetherbean wrote:
Nevermind, someone just gave me an idea that I think will work
fine...he said to fseek tot he end of the file and then do an ftell and
if it is 0 then the file is empty


Alternatively, if you want to avoid actually having to open each file,
until you're confident that it's non-empty, then you could use stat().
As an example, check out the code below.

One caveat, if you use stat(), you'll find out the size of the file at
the time of the stat() call. So, in principle, it's possible for the
file to get truncated or deleted before you actually open it up and do
anything with it.

-Dan

get_file_size.c
----------------------------------------------------------
#include <stdio.h>
#include <sys/stat.h>

int main(int argc, char *argv[]) {
int i;

if (argc == 1) {
fprintf(stderr, "Usage:\n\t%s (file1) (file2) .....\n", argv[0]);
return -1;
}

for (i = 1; i < argc; i++) {
struct stat stat_record;
printf("%s - ", argv[i]);
if (stat(argv[i], &stat_record))
printf("Can't stat (does file exist?)\n");
else if (!stat_record.st_size) printf("Empty file\n");
else {
/* Now you can open up the file an do what ever it is your going
to do - since it is non-empty
(or more technically correct probably still non-empty) */
printf(" Non-empty file (%d bytes)\n", stat_record.st_size);
}
}
return 0;
}
----------------------------------------------------------

Nov 14 '05 #4
"wetherbean" <bj******@gmail.com> wrote:
# Nevermind, someone just gave me an idea that I think will work
# fine...he said to fseek tot he end of the file and then do an ftell and
# if it is 0 then the file is empty

The return value of ftell is not guarenteed to be meaningful except to fseek.
It might be a file length, or something else altogether.

In ANSI C, open the file and see if you can read anything before getting an EOF.
Your system might provide other calls that don't require openning the file.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
What kind of convenience store do you run here?
Nov 14 '05 #5
On Sat, 23 Apr 2005 16:39:39 -0600, Daniel Cer wrote:
wetherbean wrote:
Nevermind, someone just gave me an idea that I think will work
fine...he said to fseek tot he end of the file and then do an ftell and
if it is 0 then the file is empty


Alternatively, if you want to avoid actually having to open each file,
until you're confident that it's non-empty, then you could use stat().


There is no function called stat in Standard C which is what is discussed
here.

Rob Gamble
Nov 14 '05 #6
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> writes:
"wetherbean" <bj******@gmail.com> wrote:
Nevermind, someone just gave me an idea that I think will work
fine...he said to fseek tot he end of the file and then do an ftell and
if it is 0 then the file is empty


The return value of ftell is not guarenteed to be meaningful except
to fseek. It might be a file length, or something else altogether.


[Quote character '#' changed to '>' as usual.]

Actually, the result of ftell() is meaningful if the file is opened
in binary mode.

C99 7.19.9.4p2:

The ftell function obtains the current value of the file position
indicator for the stream pointed to by stream. For a binary
stream, the value is the number of characters from the beginning
of the file. For a text stream, its file position indicator
contains unspecified information,
[snip]

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #7
On Sun, 24 Apr 2005 00:35:26 GMT, Keith Thompson <ks***@mib.org> wrote
in comp.lang.c:
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> writes:
"wetherbean" <bj******@gmail.com> wrote:
Nevermind, someone just gave me an idea that I think will work
fine...he said to fseek tot he end of the file and then do an ftell and
if it is 0 then the file is empty


The return value of ftell is not guarenteed to be meaningful except
to fseek. It might be a file length, or something else altogether.


[Quote character '#' changed to '>' as usual.]

Actually, the result of ftell() is meaningful if the file is opened
in binary mode.

C99 7.19.9.4p2:

The ftell function obtains the current value of the file position
indicator for the stream pointed to by stream. For a binary
stream, the value is the number of characters from the beginning
of the file. For a text stream, its file position indicator
contains unspecified information,
[snip]


The ftell() function is indeed meaningful for binary files, but using
fseek() first to get to the end, so ftell() can return the file size,
it not.

7.19.9.2 P3:

A binary stream need not meaningfully support fseek calls with a
whence value of SEEK_END.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #8
Robert Gamble wrote:

There is no function called stat in Standard C which is what is discussed
here.

Rob Gamble


Even though stat() is not part of the current C standard, it is
available to C developers, in some form or another, on most of the
systems they might target. For example, the code should work as is on
systems like Linux, Mac OS X, Solaris, and perhaps even OpenVMS.

Even on Microsoft Windows, I think the only change would be to use
_stat() rather than stat(), with this function still being included from
the same header file, sys/stat.h. Moreover, the structure populated by
_stat() still contains a field 'st_size' that indicates the size of the
file in question and returns 0 on success or a non-zero value on failure.

Anyhow, using stat(), or a stat like function, should be a more
efficient than having to open each file and then attempting to read from
it to see if it contains any data. And, it seems a bit more elegant.
But, yeah, I probably should have said something about it being part of
the POSIX standard and/or system dependent rather than being Standard C.

-Dan

Nov 14 '05 #9
>Robert Gamble wrote:
There is no function called stat in Standard C which is what is discussed
here.

In article <42**************@gmail.com>
Daniel Cer <Da********@gmail.com> wrote:Even though stat() is not part of the current C standard, it is
available to C developers, in some form or another, on most of the
systems they might target.
Perhaps. It is certainly available in all POSIX-conformant systems.
Still, "available in most systems" is obviously not quite as good
as "available in all systems on which files are available".
Anyhow, using stat(), or a stat like function, should be a more
efficient than having to open each file and then attempting to read from
it to see if it contains any data.


Have you tested this? In particular, have you compared the
performance of the sequence:

stat the file to find out if it is empty.
then, open the file and if it was empty earlier, write an ID, but if it
was not empty, read the ID;
then, write any data;
finally, close the file.

vs:

open the file;
try to read the ID; if none available, write an ID;
then, write any data;
finally, close the file.

? Try it (with a large number of files) and see if you get the
results that *I* expect, namely, that the latter should be slightly
faster. (How much faster depends on the system. The reason is
that, on modern systems, "look up file by name" happens to be the
slowest file-related operation the system ever does. The "stat
then open" sequence looks up the file name twice. The "open then
manipulate" sequence looks up the file name just once. You can
achieve the same performance as the "test read" method by using
fstat() once the file is open, of course, if you are on a POSIX
system.)

Of course, the "best" way to open the file is often to use the
non-C-Standard function that says "open this file for reading and
writing, creating it if necessary, but not discarding existing
data". Standard C has only three ways to open for both reading
and writing:

method1 = fopen(filename1, "r+"); /* or r+b */
method2 = fopen(filename2, "w+"); /* or w+b */
method3 = fopen(filename2, "a+"); /* or a+b */

The file opened via method 1 must already exist -- if not, the
fopen() must fail and method1 will be NULL. Method 2 will create
the file, but an existing file opened via method 2 has any existing
data removed first, which is clearly not what is wanted in this
case. Method 3 will also create the file if it does not yet exist,
but has the drawback that *every* write to the file will append,
whether or not you positioned the file elsewhere with fseek().
If this is what you wanted, great, but if not -- well, there
really ought to be a variation on "r+" meaning "create file if
needed". Perhaps "r+c", or perhaps "R+" or "c+", for instance.

(If you have a POSIX system, you can use:

fd = open(filename, O_RDWR | O_CREAT, mode); /* but not O_TRUNC */

to get the actual file created if needed, followed by an fdopen()
call with either "r+" or "w+" to get the C-style "FILE *" stream.
Why an appropriate mode name was not put into C99 is something of
a mystery to me, though.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #10
Chris Torek wrote:
In article <11*********************@o13g2000cwo.googlegroups. com>
wetherbean <bj******@gmail.com> wrote:
Hi group..I am writing a playlist management protocol where I have a
file that holds all the playlists and a file that holds all the
songs....before a playlist is created I need to check to see if the
playlist file is empty so that I can assign an integer value to a
playlist id field if it is the first playlist being written to the
file....can anyone help?? Thanks in advance

Definition: a file is "empty" if you cannot read anything from it.
(Is there a potential flaw in this definition? [I say yes, but
this is an exercise; you are supposed to identify potential flaws,
not just answer "yes" or "no". :-) ])

Conclusion: open the file and try to read from it. If you get
some data, it is not empty. If you get EOF immediately, it is
empty.


Leave it to Chris to cut through to the chase and give the KISS answer.

Anyway, this is how I used to do it many moons ago, but now that we have
long longs and files > 2 gigs are common place I will have to rewrite my
code.

/************************************************** ********************/
/* File Id. filelen.c. */
/* Author: Stan Milam. */
/* Date Written: 5 May 92. */
/* Description: */
/* Implement a function to determine the size of a file in bytes. */
/* Useful for determining if a file is empty too. */
/* */
/* (c) Copyright 2005 by Stan Milam. */
/* All rights reserved. */
/* */
/************************************************** ********************/

#include <stdio.h>
#include <sys/types.h>
#ifdef _UNIX
# include <unistd.h>
#else
# if defined (__TURBOC__) || defined (__POWERC)
# include <io.h>
# endif
#endif

/* $Revision$ */
extern char tb_copyright[];

/************************************************** ********************/
/* Name: */
/* filelength(). */
/* */
/* Synopsis: */
/* #include "toolbox.h" */
/* long filelength( in fd ); */
/* */
/* Description: */
/* This function will return the length of a file in bytes. */
/* */
/* Arguments: */
/* int fd - A file descriptor. */
/* */
/* Returns Value: */
/* A value of type long representing the size of the file. -1L is */
/* returned when an error occurs. */
/* */
/************************************************** ********************/

long
filelength (int fd)
{
long rv, here;

if (( here = lseek(fd, 0L, SEEK_CUR)) == -1L )
rv = -1L;
else {
rv = lseek(fd, 0L, SEEK_END);
lseek(fd, here, SEEK_SET);
}
return rv;
}
Nov 14 '05 #11
>>Anyhow, using stat(), or a stat like function, should be a more
efficient than having to open each file and then attempting to read from
it to see if it contains any data.

Have you tested this? In particular, have you compared the
performance of the sequence:

stat the file to find out if it is empty.
then, open the file and if it was empty earlier, write an ID, but if it
was not empty, read the ID;
then, write any data;
finally, close the file.

vs:

open the file;
try to read the ID; if none available, write an ID;
then, write any data;
finally, close the file.


Hrm....I reread the original post by wetherbean. It looks like, for what
s/he is trying to do, you're right using the fopen approach is the
better way to go.

The post I replied to just mentions "How do I check if a file is empty
in C?" and a solution involving opening the file, fseeking to the end of
the file and then looking at the value of ftell to see if it's empty or
not.

Going off of just that, I thought, gee it seems like checking if a file
is empty or not by using fopen(), fseek(), ftell(), and then presumably
fclose() is much more complicated than just a single call to stat().
Also, the fopen(), fseek()..... sequence might involve the C library
reading part of the file into a buffer in preparation for calls that
normally come after commands like fopen, e.g. fgets, fgetc.

In contrast, the stat() approach only requires one command, and will
probably only involve the system retrieving the meta data associated
with the file(s). This meta data would also presumably be read in by the
underlying OS whenever fopen is called as well. Also, stat(), or
something very similar to it, for example, _stat() on Windows, is
ubiquitous enough that there's a >95% chance** that it's available on
whatever system the original poster is using.

So, if someone is just interested in whether a file is empty or not, for
example, if they just want to build a list of either empty or non-empty
files, using stat()/_stat() seems like a fairly reasonable approach. Or,
at least, something a programmer should be aware of when deciding what
approach to take.

Anyhow, like I said above, given what wetherbean is trying to do (i.e.
the file is going to be written to after the empty/non-empty check),
then, yeah, using the approach you suggested, something like fopen() +
fgetc() with a test for an immediate EOF, seems like the way to go.

-Dan

** Okay, this value was carefully obtained by the rule that "70% of
statistics are made up on the spot". But, it's still not entirely baseless.
Nov 14 '05 #12
In article <42**************@gmail.com>
Daniel Cer <Da********@gmail.com> wrote:
The post I replied to just mentions "How do I check if a file is empty
in C?" and a solution involving opening the file, fseeking to the end of
the file and then looking at the value of ftell to see if it's empty or
not.
(Which is not a 100% reliable method, due to the restrictions on
seek positions -- ANSI/ISO C says nothing at all about text files,
and says that binary files may contain arbitrary padding. Of course
it works on most real systems, especially for simple empty/nonempty
tests.)
In contrast, the stat() approach only requires one [call], and will
probably only involve the system retrieving the meta data associated
with the file(s).
Yes; although as it happens, opening a file is usually just about
the same amount of work. (The "extra" work in opening the file,
if any, lies in allocating data structures to track the open file.
But, just to take an example of a system I work on now: in vxWorks,
stat() is implemented internally as open() followed by fstat()
followed by close() -- so there is no savings at all! Indeed,
virtually all operations in vxWorks require opening the file first,
which may be a problem for POSIX semantics. A POSIX system allows
renaming or removing a file that you have no permission to open,
for instance.)
This meta data would also presumably be read in by the
underlying OS whenever fopen is called as well. Also, stat(), or
something very similar to it, for example, _stat() on Windows, is
ubiquitous enough that there's a >95% chance** that it's available on
whatever system the original poster is using.
It is pretty darn common -- but note that issues like "sometimes
it is named _stat" are already an annoyance.
So, if someone is just interested in whether a file is empty or not, for
example, if they just want to build a list of either empty or non-empty
files, using stat()/_stat() seems like a fairly reasonable approach.


To build a list of files, you usually have to do something else
that cannot be done in ANSI/ISO C: read directories. There is no
harm going beyond the Standard in this case. If you have to do
something that is impossible in Standard C, you might as well use
non-Standard C. :-)

The trickier tradeoffs come in when you *can* do it -- whatever
"it" is -- in Standard C, but you can do it "better" with some
non-standard calls. Now you face the same problem as the fellow
who wants to buy a car, and can get a clapped-out Yugo for a hundred
bucks, or a nice shiny slightly-used Lexus or BMW for a mere $25
grand: "good, fast, cheap -- pick any two." :-)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #13
Hello...thanks for all your input guys....this was the biggest response
I have had yet. I have found for my purpose the fseek.ftell method
seems to be the best...although I did encounter a small
problem....after I check if the file is empty I have to call rewind()
so fread in a loop from the beginning of the file to get the playlist
id of the last file entry before I can write the new playlist entry to
the file.....this part of the code is successful but within my
while(!feof) the code is doing an extra run as if the EOF has gotten
pushed up a line....can anyone explain this?? Here is the portion of
my code where I was trying to test if the fwrites were actually
producing the correct info....if anyone needs more explanation let me
know...Thanks in advance

weatherbean
fseek(list_file,0,SEEK_END);

if(ftell(list_file)==0){
//printf("ftell=0\n");
playlist.list_id=1;

fwrite(&playlist,sizeof(playlist),1,list_file);
}

else if(ftell(list_file)!=0){
rewind(list_file);
while(!feof(list_file)){

fread(&playlist,sizeof(playlist),1,list_file);

printf("%s\n",playlist.list_name);
printf("%d\n",playlist.list_id);

prev_id=playlist.list_id;

}//end while

playlist.list_id=prev_id+1;

strcpy(playlist.list_name,listname);

fwrite(&playlist,sizeof(playlist),1,list_file);

Nov 14 '05 #14
"wetherbean" <bj******@gmail.com> writes:
Hello...thanks for all your input guys....this was the biggest response
I have had yet. I have found for my purpose the fseek.ftell method
seems to be the best...although I did encounter a small
problem....after I check if the file is empty I have to call rewind()
so fread in a loop from the beginning of the file to get the playlist
id of the last file entry before I can write the new playlist entry to
the file.....this part of the code is successful but within my
while(!feof) the code is doing an extra run as if the EOF has gotten
pushed up a line....can anyone explain this?? Here is the portion of
my code where I was trying to test if the fwrites were actually
producing the correct info....if anyone needs more explanation let me
know...Thanks in advance


The feof() fucntion tells you that the last read operation hit the end
of the file, not that the next one is going to. (It also doesn't tell
you when an error occurs, so your loop could be an infinite one.)

fread() returns the number of bytes it actually read; use that to
determine when you've reached the end of the file. (You can then use
the feof() function to distinguish between reaching the end of the
file and encountering an error.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #15
Thanks...that worked great....I also encountered a problem putting with
putting my switch into a loop.....I want all of the user errors to
return to the second menu I have but when I try to put the second
switch in my program in a loop it segfaults...I think it might be
easier to show you what I mean if I just post the entire code here...I
know some consider it bad practice to put switch statements in loops
but at this point I am just trying to make it work....lol..any
suggestions?? Thanks in advance

Wetherbean
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct song_rec{
char artist[30];
char album[35];
int track;
int song_id;};

struct playlist_rec{
char list_name[20];
int list_id;};

struct user_rec{
char name[15];
int pw;};
int main(int argc,char**argv) {

FILE* user_file;
FILE* list_file;
FILE* song_file;
struct user_rec user;
struct playlist_rec playlist;
struct song_rec song;
int choice=0,found=0,password=0,registered=0,offset=0;
int first=0,choice2=0,prev_id=0,count=0,list_id;
char uname[15];
char listname[20];
char song_file_name[25];
char list_file_name[25];

printf("1)REGISTER\n");
printf("2)LOGIN\n");
printf("->");
scanf("%d",&choice);

switch(choice){

case 1:
while(registered!=1){
found=0;
printf("Enter desired login name: ");
scanf("%s",uname);
printf("%s\n",uname);

user_file=fopen("user_file.data","a+");

while(!feof(user_file)&&found!=1){
fread(&user,sizeof(user),1,user_file);

if (strcmp(uname,user.name)==0){
found=1;
printf("Login name already in use\n");
fclose(user_file);
}
}//end while

if (found==0){
registered=1;
printf("Enter desired password: ");
scanf("%d",&password);
strcpy(user.name,uname);
user.pw=password;
fwrite(&user,sizeof(user),1,user_file);
printf("Registration Successful\n");
printf("Username: %s\n Password:
%d\n",user.name,user.pw);
fclose(user_file);}

}
break;

case 2:

user_file=fopen("user_file.data","rb");

printf("Enter username: ");
scanf("%s",uname);
printf("Enter password: ");
scanf("%d",&password);
while(!feof(user_file)&&strcmp(user.name,uname)!=0 ){
fread(&user,sizeof(user),1,user_file);
if (strcmp(user.name,uname)==0 && password==user.pw){
printf("Logged In....\n\n");
sprintf(list_file_name,"%s.plst",user.name);
sleep(1);}

else{
printf("User name and password do not
match\n");
exit(1);}
}

case 3:

/******ANSI CODE FOR CLEAR SCREEN*******/

printf(" \033[2J");

//------------------------------------ >
//I want the code after this to loop
// until choice2==7 but it segfaults when I add in the while loop

// while(1){

printf("Hello %s, Enter the number of your
choice\n");
printf("1)Create Playlist\n");
printf("2)Add song to a playlist\n");
printf("3)Delete Song From a playlist\n");
printf("4)Randomize playlist\n");
printf("5)Delete Playlist\n");
printf("6)Display Playlist File\n");
printf("7)Exit\n");
printf("->");
scanf("%d",&choice2);

switch(choice2){

/**************CREATE
PLAYLIST****************************/

case 1:
printf("Enter name of new playlist: ");
scanf("%s",listname);
//
sprintf(list_file_name,"%s.plst",user.name);
list_file=fopen(list_file_name,"a+");
/**************stopped working
here**************/
fseek(list_file,0,SEEK_END);

if(ftell(list_file)==0){
//printf("ftell=0\n");
playlist.list_id=1;
strcpy(playlist.list_name,listname);

fwrite(&playlist,sizeof(playlist),1,list_file);
}

else if(ftell(list_file)!=0){
rewind(list_file);

while(fread(&playlist,sizeof(playlist),1,list_file )!=0){

if
(strcmp(playlist.list_name,listname)==0){
printf("Playlist Name
already in use\n");
exit(0);}
printf("%s\n",playlist.list_name);
printf("%d\n",playlist.list_id);

prev_id=playlist.list_id;

}//end while

playlist.list_id=prev_id+1;

strcpy(playlist.list_name,listname);

fwrite(&playlist,sizeof(playlist),1,list_file);
}//else if

//printf("%d\n",playlist.list_id);
fclose(list_file);

break;
/**********************ADD SONG TO
PLAYLIST*************************/
case 2:
printf("Enter name of playlist to add to: ");
scanf("%s",listname);
list_file=fopen(list_file_name,"a+");
printf("Enter Song Artist: ");
scanf("%s",song.artist);
printf("Enter Album Title: ");
scanf("%s",song.album);
printf("Enter Track Number: ");
scanf("%d",&song.track);

while(!feof(list_file)){

fread(&playlist,sizeof(playlist),1,list_file);

if(strcmp(playlist.list_name,listname)==0){
song.song_id=playlist.list_id;
}
}
fclose(list_file);
sprintf(song_file_name,"%s.sng",uname);
song_file=fopen(song_file_name,"a");
fwrite(&song,sizeof(song),1,song_file);

fclose(song_file);

break;
/****************************DISPLAY CURRENT
PLAYLISTS*************************************/
case 6:
list_file=fopen(list_file_name,"a+");

while(fread(&playlist,sizeof(playlist),1,list_file )){

printf("%s\n",playlist.list_name);

}

case 7:
exit(0);
} //end switch 2
// } end while(1)

} //end switch 1

}

Nov 14 '05 #16
Thanks...that worked great....I also encountered a problem putting with
putting my switch into a loop.....I want all of the user errors to
return to the second menu I have but when I try to put the second
switch in my program in a loop it segfaults...I think it might be
easier to show you what I mean if I just post the entire code here...I
know some consider it bad practice to put switch statements in loops
but at this point I am just trying to make it work....lol..any
suggestions?? Thanks in advance

Wetherbean
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct song_rec{
char artist[30];
char album[35];
int track;
int song_id;};

struct playlist_rec{
char list_name[20];
int list_id;};

struct user_rec{
char name[15];
int pw;};
int main(int argc,char**argv) {

FILE* user_file;
FILE* list_file;
FILE* song_file;
struct user_rec user;
struct playlist_rec playlist;
struct song_rec song;
int choice=0,found=0,password=0,registered=0,offset=0;
int first=0,choice2=0,prev_id=0,count=0,list_id;
char uname[15];
char listname[20];
char song_file_name[25];
char list_file_name[25];

printf("1)REGISTER\n");
printf("2)LOGIN\n");
printf("->");
scanf("%d",&choice);

switch(choice){

case 1:
while(registered!=1){
found=0;
printf("Enter desired login name: ");
scanf("%s",uname);
printf("%s\n",uname);

user_file=fopen("user_file.data","a+");

while(!feof(user_file)&&found!=1){
fread(&user,sizeof(user),1,user_file);

if (strcmp(uname,user.name)==0){
found=1;
printf("Login name already in use\n");
fclose(user_file);
}
}//end while

if (found==0){
registered=1;
printf("Enter desired password: ");
scanf("%d",&password);
strcpy(user.name,uname);
user.pw=password;
fwrite(&user,sizeof(user),1,user_file);
printf("Registration Successful\n");
printf("Username: %s\n Password:
%d\n",user.name,user.pw);
fclose(user_file);}

}
break;

case 2:

user_file=fopen("user_file.data","rb");

printf("Enter username: ");
scanf("%s",uname);
printf("Enter password: ");
scanf("%d",&password);
while(!feof(user_file)&&strcmp(user.name,uname)!=0 ){
fread(&user,sizeof(user),1,user_file);
if (strcmp(user.name,uname)==0 && password==user.pw){
printf("Logged In....\n\n");
sprintf(list_file_name,"%s.plst",user.name);
sleep(1);}

else{
printf("User name and password do not
match\n");
exit(1);}
}

case 3:

/******ANSI CODE FOR CLEAR SCREEN*******/

printf(" \033[2J");

//------------------------------------ >
//I want the code after this to loop
// until choice2==7 but it segfaults when I add in the while loop

// while(1){

printf("Hello %s, Enter the number of your
choice\n");
printf("1)Create Playlist\n");
printf("2)Add song to a playlist\n");
printf("3)Delete Song From a playlist\n");
printf("4)Randomize playlist\n");
printf("5)Delete Playlist\n");
printf("6)Display Playlist File\n");
printf("7)Exit\n");
printf("->");
scanf("%d",&choice2);

switch(choice2){

/**************CREATE
PLAYLIST****************************/

case 1:
printf("Enter name of new playlist: ");
scanf("%s",listname);
//
sprintf(list_file_name,"%s.plst",user.name);
list_file=fopen(list_file_name,"a+");
/**************stopped working
here**************/
fseek(list_file,0,SEEK_END);

if(ftell(list_file)==0){
//printf("ftell=0\n");
playlist.list_id=1;
strcpy(playlist.list_name,listname);

fwrite(&playlist,sizeof(playlist),1,list_file);
}

else if(ftell(list_file)!=0){
rewind(list_file);

while(fread(&playlist,sizeof(playlist),1,list_file )!=0){

if
(strcmp(playlist.list_name,listname)==0){
printf("Playlist Name
already in use\n");
exit(0);}
printf("%s\n",playlist.list_name);
printf("%d\n",playlist.list_id);

prev_id=playlist.list_id;

}//end while

playlist.list_id=prev_id+1;

strcpy(playlist.list_name,listname);

fwrite(&playlist,sizeof(playlist),1,list_file);
}//else if

//printf("%d\n",playlist.list_id);
fclose(list_file);

break;
/**********************ADD SONG TO
PLAYLIST*************************/
case 2:
printf("Enter name of playlist to add to: ");
scanf("%s",listname);
list_file=fopen(list_file_name,"a+");
printf("Enter Song Artist: ");
scanf("%s",song.artist);
printf("Enter Album Title: ");
scanf("%s",song.album);
printf("Enter Track Number: ");
scanf("%d",&song.track);

while(!feof(list_file)){

fread(&playlist,sizeof(playlist),1,list_file);

if(strcmp(playlist.list_name,listname)==0){
song.song_id=playlist.list_id;
}
}
fclose(list_file);
sprintf(song_file_name,"%s.sng",uname);
song_file=fopen(song_file_name,"a");
fwrite(&song,sizeof(song),1,song_file);

fclose(song_file);

break;
/****************************DISPLAY CURRENT
PLAYLISTS*************************************/
case 6:
list_file=fopen(list_file_name,"a+");

while(fread(&playlist,sizeof(playlist),1,list_file )){

printf("%s\n",playlist.list_name);

}

case 7:
exit(0);
} //end switch 2
// } end while(1)

} //end switch 1

}

Nov 14 '05 #17
Jack Klein <ja*******@spamcop.net> wrote:
On Sun, 24 Apr 2005 00:35:26 GMT, Keith Thompson <ks***@mib.org> wrote
in comp.lang.c:
Actually, the result of ftell() is meaningful if the file is opened
in binary mode.

C99 7.19.9.4p2:

The ftell function obtains the current value of the file position
indicator for the stream pointed to by stream. For a binary
stream, the value is the number of characters from the beginning
of the file. For a text stream, its file position indicator
contains unspecified information,
[snip]


The ftell() function is indeed meaningful for binary files, but using
fseek() first to get to the end, so ftell() can return the file size,
it not.


True, but the OP wanted to know whether the file is empty, not how large
it is if it's not. So ISTM that opening the file in text mode, fseek()
to the start of the file, save the indicator returned by ftell(),
fseek() to the end, compare the saved value to what ftell() returns now,
will work. If the two indicators are equal, the file is empty; if
they're not, you don't know _what_ the file size is, but you do know
that it's not zero.

Richard
Nov 14 '05 #18
On Tue, 26 Apr 2005 13:24:47 +0000, Richard Bos wrote:
Jack Klein <ja*******@spamcop.net> wrote:
On Sun, 24 Apr 2005 00:35:26 GMT, Keith Thompson <ks***@mib.org> wrote
in comp.lang.c:
> Actually, the result of ftell() is meaningful if the file is opened
> in binary mode.
>
> C99 7.19.9.4p2:
>
> The ftell function obtains the current value of the file position
> indicator for the stream pointed to by stream. For a binary
> stream, the value is the number of characters from the beginning
> of the file. For a text stream, its file position indicator
> contains unspecified information,
> [snip]


The ftell() function is indeed meaningful for binary files, but using
fseek() first to get to the end, so ftell() can return the file size,
it not.


True, but the OP wanted to know whether the file is empty, not how large
it is if it's not. So ISTM that opening the file in text mode, fseek()
to the start of the file, save the indicator returned by ftell(),
fseek() to the end, compare the saved value to what ftell() returns now,
will work. If the two indicators are equal, the file is empty; if
they're not, you don't know _what_ the file size is, but you do know
that it's not zero.

AFAICT the Deathstation could return a random but distinct value from each
call to ftell() in a text stream and maintaain an internal lookup table
to find the true offset in fseek(). So the fact that two return values are
different doesn't mean they represent different offsets.

Lawrence
Nov 14 '05 #19
Chris Torek wrote:
[ snip ]
Conclusion: open the file and try to read from it. If you get
some data, it is not empty. If you get EOF immediately, it is
empty.


Caveat: On non-Unix systems, open the file in "rb" binary mode. It is
possible for a non-empty file to have 0x1a its first byte. In text mode
reading this byte can give you EOF immediately (not what you wanted to see).

--
Joe Wright mailto:jo********@comcast.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #20

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Paul Telco | last post: by
30 posts views Thread by S. van Beek | last post: by
1 post views Thread by Oleg Ogurok | last post: by
3 posts views Thread by puja | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.