Mimicking CAT or TYPE in C

M

mario.demiguel

Hello all, I believe I know the basics of what I need to do, but some
clarification would help.

I want to open a text file using functions from stdio.h. Then I want
to output the text in this file to the screen. This is meant to be
part of a Windows console app.

Currently, I have the following, which works but has problems:

#include <stdio.h>
int main(int argc, char *argv[])
{
const char mode[1]={'r'};
FILE * test;
char str [sizeof(test)];

test = fopen("C:\\test.txt", mode);
fread(str,sizeof(str[0]),50,test);
/*I need to find a better way to come up with the value. 50 is
just a magic number that happens to work. 200 for instance wouldn't*/

printf(str);
}

Is there a better way to do this? Also, when is it appropriate to use
fscanf instead of freadf? Thanks in advance.
 
L

Lew Pitcher

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello all, I believe I know the basics of what I need to do, but some
clarification would help.

I want to open a text file using functions from stdio.h. Then I want
to output the text in this file to the screen. This is meant to be
part of a Windows console app.

Currently, I have the following, which works but has problems:

#include <stdio.h>
int main(int argc, char *argv[])
{
const char mode[1]={'r'};
FILE * test;
char str [sizeof(test)];

test = fopen("C:\\test.txt", mode);
fread(str,sizeof(str[0]),50,test);
/*I need to find a better way to come up with the value. 50 is
just a magic number that happens to work. 200 for instance wouldn't*/

printf(str);
}

Is there a better way to do this?

Probably. It depends on what you want to accomplish and what your limits
are.

For instance, I'd probably take the 'bulletproof' way out and code
something like

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
FILE *file;
int datum;

if ((file= fopen("C:\\test.txt","r") == 0)
return EXIT_FAILURE;

while ((datum = fgetc(file)) != EOF) putchar(datum);
fclose(file);

return EXIT_SUCCESS;
}

Also, when is it appropriate to use
fscanf instead of freadf?

When you have values that you want to break out of the data, and already
have adequate protection against bad input.
Thanks in advance.


- --

Lew Pitcher, IT Specialist, Enterprise Data Systems
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFDQt/uagVFX4UWr64RAsU/AKDSFDoqZSZEjn5Zin71ZhMwsKjzggCaA4cA
XFsFOvvHCYk1hvaWuZIBg6k=
=P5xw
-----END PGP SIGNATURE-----
 
E

Eric Sosman

Hello all, I believe I know the basics of what I need to do, but some
clarification would help.

I want to open a text file using functions from stdio.h. Then I want
to output the text in this file to the screen. This is meant to be
part of a Windows console app.

Currently, I have the following, which works but has problems:

#include <stdio.h>
int main(int argc, char *argv[])
{
const char mode[1]={'r'};

const char mode[2] = { 'r', '\0' };
or
const char mode[] = { 'r', '\0' };

.... but there's an even simpler way; see below.
FILE * test;
char str [sizeof(test)];

You've now got an array whose size is that of a
`FILE*', a pointer to an I/O stream. The size of this
pointer is unrelated to the amount of data in the file,
and is unlikely to be what you want.
test = fopen("C:\\test.txt", mode);

test = fopen("C:\\test.txt", "r");
if (test == NULL)
die_horribly();
fread(str,sizeof(str[0]),50,test);
/*I need to find a better way to come up with the value. 50 is
just a magic number that happens to work. 200 for instance wouldn't*/

See Question 19.12 in the comp.lang.c Frequently
Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html
printf(str);
}

Is there a better way to do this?

Yes, and not only better but far simpler as well.
Since there's a strong odor of homework about the place
I'll say only this much: Do you think you could copy file
in smaller chunks, instead of trying (as I think you're
trying) to read the entire thing into memory first?
Also, when is it appropriate to use
fscanf instead of freadf? Thanks in advance.

Assuming "freadf" is a typo for "fread," the two
functions aren't very much alike. fscanf() can be tricky
to use well -- but then again, it can be made to do many
useful tricks. fread() is easier to use, but less flexible.
getc() is easier than either of them. Hint, hint.
 
M

mario.demiguel

Thanks, though this isn't for a homework assignment, I understand your
discretion. Seriously, I got my bachelor's degree in May, but Arizona
State University doesn't teach C, just java and I wanted to expand my
palette. I can tell you all about semaphores, Turing Machines,
red-black trees, programming assembly on a Motorola 86HC11, and what an
activation record is.

I read that gets() is depreciated. getc() doesn't appear to be. Any
comments?

I can see the problems with reading the whole file into memory first,
especially if it gets quite large, but if I take your advice and copy
the file in smaller chunks, where do I store the chunks? Perhaps copy
a chunk, print it to stdout then proceed to the next chunk.

You say there is a far simpler way to do this, by simpler, do you mean
shorter or easier to read?
 
N

Nick Keighley

Thanks, though this isn't for a homework assignment, I understand your
discretion. Seriously, I got my bachelor's degree in May,

<snip>

but obviously your degree didn't explain how to leave context in a
news-group post...
I read that gets() is depreciated. getc() doesn't appear to be. Any
comments?

gets() reads a series of characters *without limit*, getc() reads a
single character. It is easy to use getc() without a problem. It is
pretty well impossible to use gets() without a potential problem.

See the FAQ at http://www.eskimo.com/~scs/C-faq/faq.html
in particular FAQ 12.23 "Why does everyone say not to use gets()?"
I can see the problems with reading the whole file into memory first,
especially if it gets quite large, but if I take your advice and copy
the file in smaller chunks, where do I store the chunks?

malloc()?

<snip>


--
Nick Keighley

"Good grief. If you want to start correcting Nick Keighley's correct
response with unadulterated horse manure, maybe it's time
to put you back to bed in the old killfile."
Dann Corbit
 
J

John Bode

Thanks, though this isn't for a homework assignment, I understand your
discretion. Seriously, I got my bachelor's degree in May, but Arizona
State University doesn't teach C, just java and I wanted to expand my
palette. I can tell you all about semaphores, Turing Machines,
red-black trees, programming assembly on a Motorola 86HC11, and what an
activation record is.

I read that gets() is depreciated. getc() doesn't appear to be. Any
comments?

gets() has no way to prevent you from writing beyond the limits of your
input buffer; for example, if your target buffer is sized to hold 10
chars, and the user types in 100 chars, 90 of those chars are going to
be written to memory outside of that buffer, potentially clobbering
something important. fgets() allows you to specify a maximum number of
characters to read, so it's safer. getc() only retrieves one character
at a time and doesn't try to save it to a buffer, so there's no
potential for accidental overflow.
I can see the problems with reading the whole file into memory first,
especially if it gets quite large, but if I take your advice and copy
the file in smaller chunks, where do I store the chunks? Perhaps copy
a chunk, print it to stdout then proceed to the next chunk.

Exactly. Use fgets() to read in N chars, write them to the screen,
repeat. Here's a quick-n-dirty example:

void dumpFile(FILE *f)
{
char inbuf[81];
int moreData = 1;

while (moreData)
{
if (fgets(inbuf, sizeof inbuf, f) != NULL)
{
printf("%s", inbuf);
}
else
{
if (feof(f))
{
/**
* Reached end-of-file.
*/
moreData = 0;
}
else if (ferror(f))
{
/**
* Error on read. This may or may not be
* a recoverable error, but handling it
* is beyond the scope of this example,
* so we'll just exit the loop at this
* point.
*/
moreData = 0;
}
}
}
}
You say there is a far simpler way to do this, by simpler, do you mean
shorter or easier to read?

See above.
 
M

mario.demiguel

No, I still claim to this day I should have gone to a trade school.
Thanks for all the help!
 
B

Barry

Thanks, though this isn't for a homework assignment, I understand your
discretion. Seriously, I got my bachelor's degree in May, but Arizona
State University doesn't teach C, just java and I wanted to expand my
palette. I can tell you all about semaphores, Turing Machines,
red-black trees, programming assembly on a Motorola 86HC11, and what an
activation record is.

I read that gets() is depreciated. getc() doesn't appear to be. Any
comments?

I can see the problems with reading the whole file into memory first,
especially if it gets quite large, but if I take your advice and copy
the file in smaller chunks, where do I store the chunks? Perhaps copy
a chunk, print it to stdout then proceed to the next chunk.

You say there is a far simpler way to do this, by simpler, do you mean
shorter or easier to read?

OT

I apologize to the group but I have to ask this.

A bachelor's in what?

Barry
 
J

Joe Wright

Hello all, I believe I know the basics of what I need to do, but some
clarification would help.

I want to open a text file using functions from stdio.h. Then I want
to output the text in this file to the screen. This is meant to be
part of a Windows console app.

Currently, I have the following, which works but has problems:

#include <stdio.h>
int main(int argc, char *argv[])
{
const char mode[1]={'r'};
FILE * test;
char str [sizeof(test)];

test = fopen("C:\\test.txt", mode);
fread(str,sizeof(str[0]),50,test);
/*I need to find a better way to come up with the value. 50 is
just a magic number that happens to work. 200 for instance wouldn't*/

printf(str);
}

Is there a better way to do this? Also, when is it appropriate to use
fscanf instead of freadf? Thanks in advance.
Try mine..

/*
Program: cat.c
Author: Joe Wright
Date: 12/25/2003
Usage: cat file1 file2 file3

cat simply copies the files, if any, to stdout.
*/
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
FILE *input = stdin;
int c;
if (argc > 1) {
while (--argc)
if ((input = fopen(*++argv, "r")) == NULL) {
fprintf(stderr, "cat: Can't open %s\n", *argv);
exit(EXIT_FAILURE);
}
else {
while ((c = getc(input)) != EOF)
putchar(c);
fclose(input);
}
}
else
while((c = getc(input)) != EOF)
putchar(c);
return EXIT_SUCCESS;
}
 
K

Kelsey Bjarnason

[snips]

#include <stdio.h>
int main(int argc, char *argv[])
{
const char mode[1]={'r'};
FILE * test;
char str [sizeof(test)];

On a typical implementation, the size of a pointer will be some four bytes;
is there some reason for using a 4-byte buffer here?
test = fopen("C:\\test.txt", mode);

fopen wants a _string_ for mode. Not a char, which is what you're passing
it (though it may not look like it). Use "r" - or "rb".
fread(str,sizeof(str[0]),50,test);

You're assuming the file opened - why?
You're using sizeof(str[0]), which is sizeof(char), which is 1. Just use
1; it's clearer. Also, that 50 is bigger than the 4 (or whatever, for your
implementation) used above - buffer overflow.
printf(str);
}


No file close? No return value?
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top