ANSI C - Filsize ?

J

Joe

Im quit new to this language so bare with me:

how do read the contens of a textfile in to a buffer?
how do i get the size of a file?

I've tried this, but it dosn't seem to work:

FILE *file1;
FILE *file2;
file1 = fopen("inputfil.txt", "r+");
file2 = fopen("inputfil.txt", "r+");

while((c = getc(file1)) != EOF)
{
filesize++;
}

unsigned char buffer[filesize];

while((c = getc(file2)) != EOF)
{
buffer = c;
for(i = 0; i< filesize-1; i++)
{
buffer = getc(file2);
}
}
 
J

Jack Klein

Im quit new to this language so bare with me:

how do read the contens of a textfile in to a buffer?
how do i get the size of a file?

I've tried this, but it dosn't seem to work:

Never just say "it doesn't seem to work", because that does not
provide enough information for anyone to help you with your problem.
At a minimum, you need to provide an explanation of what not working
means. If your compiler generates an error, you need to copy the text
and paste it into your post. If it compiles but runs incorrectly, you
need to mention what you think it should do, and what it does instead.
FILE *file1;
FILE *file2;
file1 = fopen("inputfil.txt", "r+");
file2 = fopen("inputfil.txt", "r+");

while((c = getc(file1)) != EOF)

What is the type of c? If it's a char, that could be a problem.
{
filesize++;

What is the type of filesize?
}

unsigned char buffer[filesize];

Unless you have a C99 conforming compiler, and there are not very many
of those, you can't define an array using a variable as the size. If
you need to access an amount of storage with a size not known until
run time, you need to use dynamic memory allocation, i.e., malloc() or
calloc().
while((c = getc(file2)) != EOF)
{
buffer = c;
for(i = 0; i< filesize-1; i++)
{
buffer = getc(file2);
}
}


See the FAQ for comp.lang.c, link in my signature block, particularly
section 7 which covers memory allocation in great detail.
http://www.eskimo.com/~scs/C-faq/s7.html

You did quite well at posting your code, you just need to be a little
more specific about the problem in the future.
 
D

donLouis

Im quit new to this language so bare with me:

how do read the contens of a textfile in to a buffer?

int buffer[WAY_LARGE_NUM];
int i;
i = 0;
while ((buffer = getchar() != EOF) || i < WAY_LARGE_NUM)
i++;
how do i get the size of a file?

Strictly speaking, you can't, without using a platform specific
technique.
I've tried this, but it dosn't seem to work:

This can work with a C99 compiler, with a small fix.
FILE *file1;
FILE *file2;
file1 = fopen("inputfil.txt", "r+");
file2 = fopen("inputfil.txt", "r+");

while((c = getc(file1)) != EOF)
{
filesize++;
}

unsigned char buffer[filesize];

C99 allows you to use filesize for the size of your array. C89
does not. Also for this application, I would recommend type int
for buffer.
while((c = getc(file2)) != EOF)
{
buffer = c;


What's the value of i?
for(i = 0; i< filesize-1; i++)
{
buffer = getc(file2);
}
}


Again with the C99 declaration of buffer, you could change the
above while loop to this;

i = 0;
while ((c = getc(file2)) != EOF) {
buffer = c;
i++; }

You could also drop the middle term, as well.

C99 or otherwise, do you really _need_ to know the file size in
advance? Besides getting the data into a buffer (no doubt handy),
what is the larger problem to be solved?
 
J

Jan Engelhardt

how do i get the size of a file?
Strictly speaking, you can't, without using a platform specific
technique.

Assuming that ftell() belongs to stdio belongs to ANSI C,
one /might/ be able to find out the file size. Does not work
with un-ordinary files.

long filesize(FILE *fp) {
long save = ftell(fp);
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
fseek(fp, save, SEEK_END);
return size;
}




Jan Engelhardt
--
 
D

donLouis

Assuming that ftell() belongs to stdio belongs to ANSI C,
one /might/ be able to find out the file size. Does not work
with un-ordinary files.

long filesize(FILE *fp) {
long save = ftell(fp);
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
fseek(fp, save, SEEK_END);
return size;
}

The OP's technique can be made to work as well. When I said strict,
I meant that the general problem is unsolvable.

Open question; now that I have filesize, courtesy of ftell and
friends, what do I _do_ with this information?
 
J

Joe

C99 or otherwise, do you really _need_ to know the file size in
advance? Besides getting the data into a buffer (no doubt handy),
what is the larger problem to be solved?

Believe it or not I’m trying to write a "sort of" application layer for
my own implementation of 3 layers of the OSI protocol (TL,NL,DL).

One might think; That's a big step to start programming networks layers
in C if you can't even control basic file handling, and I would be the
to agree with you.

Nevertheless, although I have never before programmed in C it’s the
demand for the assignment at my class that this project is implemented in C.

Well back to the matter at hand:

I think I need the size of the input file, so I can make the buffer I
want to send to the TP layer only the size of the input file.

I’m currently putting the input from the file in to a unsigned char
array, but I have to specify the size of this array when I create it, so
even if my input file only contains say 100 characters, the array is
potential much bigger.

Here is my code so far:

void station_a(void)
{
unsigned char c[MAX_FILE_SIZE];
unsigned char buffer[MAX_FILE_SIZE];
FILE *file;

printf("[TEST METHOD][Station %i] : Station started\n", ThisStation);
printf("[TEST METHOD][Station %i] : Trying to open inputfile\n",
ThisStation);

file = fopen("inputfile.txt", "r");

if(file==NULL)
{
printf("[TEST METHOD][Station %i] : Error: can't open inputfile\n",
ThisStation);
}
else
{
printf("[TEST METHOD][Station %i] : Inputfile opened successfully\n",
ThisStation);
printf("[TEST METHOD][Station %i] : Reading file contens->\n\n\t ");

while(fgets(c, MAX_FILE_SIZE, file)!=NULL)
{
printf("%s", c);

}
printf("\n%i", sizeof(c));
printf("\n%c", c[0]);
/*
int i;
for(i = 0;i < sizeof(c);i++)
{
printf("%s", c);
}
*/
//printf("\n%s", c[0]);


printf("\n\n");
printf("[TEST METHOD][Station %i] : Sending file\n", ThisStation);
from_user(c,ThisStation,2); //sending to next layer!!
printf("[TEST METHOD][Station %i] : Closing file\n", ThisStation);
fclose(file);
}
printf("[TEST METHOD][Station %i] : Station closing\n", ThisStation);
}
 
T

Thomas Pfaff

Jan Engelhardt said:
Assuming that ftell() belongs to stdio belongs to ANSI C,
one /might/ be able to find out the file size. Does not work
with un-ordinary files.

long filesize(FILE *fp) {
long save = ftell(fp);
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
fseek(fp, save, SEEK_END);
return size;
}

It might be worth mentioning that `fseek (fp, 0, SEEK_END);' invokes
undefined behaviour when applied to a binary stream.
 
T

Thomas Matthews

Joe said:
Im quit new to this language so bare with me:

how do read the contens of a textfile in to a buffer?
how do i get the size of a file?

I've tried this, but it dosn't seem to work:

FILE *file1;
FILE *file2;
file1 = fopen("inputfil.txt", "r+");
file2 = fopen("inputfil.txt", "r+");

while((c = getc(file1)) != EOF)
{
filesize++;
}

unsigned char buffer[filesize];

while((c = getc(file2)) != EOF)
{
buffer = c;
for(i = 0; i< filesize-1; i++)
{
buffer = getc(file2);
}
}


Out of curiosity, why aren't you using fread?
You know how big the buffer is, and fread will
read in a chunk directly into the buffer.

BTW, there is no portable method to obtain the size
of a file, because that is operating system dependent.
Some OSes translate \n\r into \n or vice-versa.
Also, some OSes might have bookkeeping information
in the file, giving actual file size to content size.


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
M

Mark McIntyre

I think I need the size of the input file, so I can make the buffer I
want to send to the TP layer only the size of the input file.

The only "standard" way to do this is a FAQ - 19:12.
while(fgets(c, MAX_FILE_SIZE, file)!=NULL)

this is going to iterate through the file, reading in MAX_FILE_SIZE
bytes, printing them out and then discarding them.
printf("%s", c);


c is a character, so you need %c here.
//printf("\n%s", c[0]);
ditto

printf("[TEST METHOD][Station %i] : Sending file\n", ThisStation);
from_user(c,ThisStation,2); //sending to next layer!!

At this point, c only contains the very last data you read in., ie the
last MAX_FILE_SIZE bytes of data. The rest got discarded...
 
J

Jan Engelhardt

It might be worth mentioning that `fseek (fp, 0, SEEK_END);' invokes
undefined behaviour when applied to a binary stream.

How is that?
Running that and
int main(void) {
FILE *fp = fopen("/proc/kcore", "rb");
printf("%ld\n", filesize(fp));
}
returns the desired 268374016 (256MB).


Jan Engelhardt
--
 
R

Richard Heathfield

Jan said:
How is that?
Running that and
int main(void) {
FILE *fp = fopen("/proc/kcore", "rb");
printf("%ld\n", filesize(fp));
}
returns the desired 268374016 (256MB).

void main() /* undefined behaviour - return type of main is not int */
{
printf("Hello world\n"); /* UB - variadic function, no prototype */
}

printed "Hello world" on one of my systems just now. That doesn't mean the
program's behaviour is well-defined.
 
P

Peter Nilsson

Thomas Pfaff said:
It might be worth mentioning that `fseek (fp, 0, SEEK_END);' invokes
undefined behaviour when applied to a binary stream.

No it doesn't. The standards merely state that the result may not be
meaningful. The call itself if ok if somewhat useless in a portable
program.
 
P

Peter Nilsson

Jan Engelhardt said:
How is that?
Running that and
int main(void) {
FILE *fp = fopen("/proc/kcore", "rb");
printf("%ld\n", filesize(fp));
}
returns the desired 268374016 (256MB).

Which would prove what? 'Seems to work just fine' is perfectly within
the scope of undefined behaviour [not that the behaviour actually is
UB.]
 
T

Thomas Pfaff

No it doesn't. The standards merely state that the result may not be
meaningful. The call itself if ok if somewhat useless in a portable
program.

It does according to N869, 7.19.3:

211 Setting the file position indicator to end-of-file, as
with fseek(file, 0, SEEK_END), has undefined behavior for
a binary stream (because of possible trailing null
characters) or for any stream with state-dependent
encoding that does not assuredly end in the initial shift
state.

Is this different in the actual standard?
 
R

Richard Heathfield

Thomas said:
It does according to N869, 7.19.3:

211 Setting the file position indicator to end-of-file, as
with fseek(file, 0, SEEK_END), has undefined behavior for
a binary stream (because of possible trailing null
characters) or for any stream with state-dependent
encoding that does not assuredly end in the initial shift
state.

Is this different in the actual standard?

The Standard does not say:

225) Setting the file position indicator to end-of-file, as with fseek(file,
0, SEEK_END), has undefined behavior for a binary stream (because of
possible trailing null characters) or for any stream with state-dependent
encoding that does not assuredly end in the initial shift state.

The reason the Standard doesn't say it is that footnotes (of which this is
one) are non-normative - which basically means that they don't count.
Having said that, it would IMHO be folly for a C programmer to ignore a
footnote like this one.
 
J

Jan Engelhardt

It does according to N869, 7.19.3:
211 Setting the file position indicator to end-of-file, as
with fseek(file, 0, SEEK_END), has undefined behavior for
a binary stream (because of possible trailing null
characters) or for any stream with state-dependent
encoding that does not assuredly end in the initial shift
state.

Well what I meant is:
why can't it just skip these null characters until it reaches EOF,
according to 211?
 
C

Chris Torek

It does according to N869, 7.19.3:
(As others pointed out, this is a footnote in the Standard, and
therefore is supposed to be ignored entirely. :) )

Well what I meant is:
why can't it just skip these null characters until it reaches EOF,
according to 211?

On systems that really do this to you -- such as VMS or CP/M --
"system-supplied" null characters are indistinguishable from
user-supplied null characters. For instance:

FILE *fp = fopen("somefile", "wb");

if (fp != NULL) {
putc(100, fp);
putc(0, fp);
fclose(fp);
}

will, on VMS, give you a 512-byte file consisting of the byte 100
decimal (0x64), followed by 511 null (0x00) bytes. Remove the
second putc(), and you get an *identical* 512-byte-long file. The
problem then becomes deciding how many null bytes to skip. (Knuth's
TeX solved this by writing a special "signature" of non-null bytes
at the end of a binary .dvi file, so that you could skip backwards
through any all-0 bytes until you found the signature. Then someone
broke it by changing the TeX code to pad to a block boundary.)
 
L

Lew Pitcher

Well what I meant is:
why can't it just skip these null characters until it reaches EOF,
according to 211?

Let's pretend that you have a CP/M text file (10 bytes of text) that you wish to
find the length of in a conforming C program. You fseek(file,0,SEEK_END) on the
file, opened as binary, and
a) are positioned 11 bytes into the file, at the 0x1a character that demarks
logical end of file, or
b) are positioned 1024 bytes into the file, at the end of the last (and first)
physical block that the file occupies.

Which is correct to you?

--
Lew Pitcher
IT Consultant, Enterprise Technology Solutions
Toronto Dominion Bank Financial Group

(Opinions expressed are my own, not my employers')
 
K

Kelsey Bjarnason

[snips]

It might be worth mentioning that `fseek (fp, 0, SEEK_END);' invokes
undefined behaviour when applied to a binary stream.

It's also worth mentioning that long won't cut it. In Win2K/NTFS, for
example, you can create files > 4Gb (or even > 4Gb, IIRC) which a long
isn't likely to cope with properly.

I presume the same is true of other OSen and/or file systems.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,139
Messages
2,570,806
Members
47,353
Latest member
TamiPutnam

Latest Threads

Top