print out a file?

A

Advocated

Just been searching google, but havent come up with anything. Just
wondering, whats the best way to print say a file.txt or other format to the
screen? A link would be great and ill read up on it. Cheers
 
C

Christopher Benson-Manica

Advocated said:
Just been searching google, but havent come up with anything. Just
wondering, whats the best way to print say a file.txt or other format to the

You could use the following C program...

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

int main( int argc, char *argv[] )
{
char buf[256];
FILE *fp;

if( argc != 2 ) {
fprintf( stderr, "Usage: %s <filename>\n", argv[0] );
return EXIT_FAILURE;
}
if( (fp=fopen(argv[1],"r")) == NULL ) {
fprintf( stderr, "Could not open file \"%s\"\n", argv[1] );
return EXIT_FAILURE;
}
while( fgets(buf,sizeof buf,fp) ) {
printf( "%s", buf );
}
printf( "\n" ); /* in case there were no newlines in the file */
fclose( fp );
return EXIT_SUCCESS;
}

(salient comments from the regulars appreciated)
 
A

Arthur J. O'Dwyer

Advocated said:
Just been searching google, but havent come up with anything. Just
wondering, whats the best way to print say a file.txt or other format
to the [screen?]

You could use the following C program...
[snip 24 lines using fgets() somewhat inappropriately]
(salient comments from the regulars appreciated)

What if you get a line in "file.txt" longer than 255 characters?
Anyway, the simple solutions are best... Use 'cat file.txt',
'type file.txt', or, if your OS doesn't have either of those,
just write your own 'cat' clone... [UNTESTED]

/* A simple 'cat' utility */

#include <stdio.h>

void process(FILE *fp)
{
if (fp == NULL) return;
while ((c=getc(fp)) != EOF)
putchar(c);
putchar('\n');
}

int main(int argc, char **argv)
{
if (argc < 2) {
process(stdin);
}
else {
int i;
for (i=1; i < argc; ++i)
process(fopen(argv));
}
return 0;
}

HTH,
-Arthur
 
K

Kevin Goodsell

Arthur said:
What if you get a line in "file.txt" longer than 255 characters?
Anyway, the simple solutions are best... Use 'cat file.txt',
'type file.txt', or, if your OS doesn't have either of those,
just write your own 'cat' clone... [UNTESTED]

/* A simple 'cat' utility */

#include <stdio.h>

void process(FILE *fp)
{
if (fp == NULL) return;
while ((c=getc(fp)) != EOF)
putchar(c);
putchar('\n');
}

int main(int argc, char **argv)
{
if (argc < 2) {
process(stdin);
}
else {
int i;
for (i=1; i < argc; ++i)
process(fopen(argv));
}
return 0;
}


You forgot to fclose() the files. It looks like doing so will require
some changes beyond just adding the call.

-Kevin
 
A

Arthur J. O'Dwyer

/* A simple 'cat' utility */

#include <stdio.h>

void process(FILE *fp)
{
if (fp == NULL) return;
while ((c=getc(fp)) != EOF)
putchar(c);
putchar('\n'); if (fp != stdin) fclose(fp);
}

int main(int argc, char **argv)
{
if (argc < 2) {
process(stdin);
}
else {
int i;
for (i=1; i < argc; ++i)
process(fopen(argv));
}
return 0;
}


You forgot to fclose() the files. It looks like doing so will require
some changes beyond just adding the call.


There. It's a hack, but I don't see anything technically wrong
with the program now. Good catch -- thanks.
BTW, is the 'if (fp != stdin)' required in the line I added? I
always have tried to avoid closing 'stdin' or 'stdout' as if they
were "regular" files, but is that something to worry about, or is it
guaranteed to work either way?

-Arthur
 
R

Russell Hanneken

Arthur said:
[snip 24 lines using fgets() somewhat inappropriately]

What if you get a line in "file.txt" longer than 255 characters?

I don't see the problem. What do you have in mind?
 
N

nrk

Arthur said:
Advocated said:
Just been searching google, but havent come up with anything. Just
wondering, whats the best way to print say a file.txt or other format
to the [screen?]

You could use the following C program...
[snip 24 lines using fgets() somewhat inappropriately]
(salient comments from the regulars appreciated)

What if you get a line in "file.txt" longer than 255 characters?
Anyway, the simple solutions are best... Use 'cat file.txt',
'type file.txt', or, if your OS doesn't have either of those,
just write your own 'cat' clone... [UNTESTED]

/* A simple 'cat' utility */

#include <stdio.h>

void process(FILE *fp)
{
if (fp == NULL) return;
while ((c=getc(fp)) != EOF)
putchar(c);
putchar('\n');
}

Warning: implicit declaration of int variable :)

-nrk.
int main(int argc, char **argv)
{
if (argc < 2) {
process(stdin);
}
else {
int i;
for (i=1; i < argc; ++i)
process(fopen(argv));
}
return 0;
}

HTH,
-Arthur
 
A

Arthur J. O'Dwyer

[snip 24 lines using fgets() somewhat inappropriately]

What if you get a line in "file.txt" longer than 255 characters?

I don't see the problem. What do you have in mind?

Three strikes in one post for me! :( You're right, in that
Chris' code does work as expected even with long lines, but
it *looks* like it shouldn't. ;) And I stand by my diagnosis
of "overly complicated," and that 'getc' is more appropriate
than 'fgets' for this application. And thus 'fgets' is
"somewhat inappropriate," right?

And as nrk points out, I was also missing the declaration of

int c;

inside function 'process'. I do that a lot in "real" code, too,
probably because the first time the variable is used is always
buried inside a bunch of parentheses.

-Arthur
 
A

Advocated

The main idea is that the user gives a filename, i.e file.c

It will try and open this file.. if not show an error. If the file is there,
it will just print the contents of it to the screen, but the filename could
be anything at all
 
K

Keith Thompson

Arthur J. O'Dwyer said:
/* A simple 'cat' utility */

#include <stdio.h>

void process(FILE *fp)
{
if (fp == NULL) return;
while ((c=getc(fp)) != EOF)
putchar(c);
putchar('\n');
}

int main(int argc, char **argv)
{
if (argc < 2) {
process(stdin);
}
else {
int i;
for (i=1; i < argc; ++i)
process(fopen(argv));
}
return 0;
}


This unconditionally prints an extra '\n' after printing each file.
 
C

Christopher Benson-Manica

Arthur J. O'Dwyer said:
What if you get a line in "file.txt" longer than 255 characters?

Um, well at least it isn't UB, right? ;)
Anyway, the simple solutions are best... Use 'cat file.txt',
'type file.txt', or, if your OS doesn't have either of those,
just write your own 'cat' clone... [UNTESTED]

Yeeeah, much better. Thanks.
 
C

Christopher Benson-Manica

Arthur J. O'Dwyer said:
Chris' code does work as expected even with long lines,

Well, it "works" without UB, although I don't think one would "expect"
long lines to be truncated :) I probably should have made some note
of that behavior in my original post. I noted elsewhere that in any
case putc() is probably better regardless.
 
A

Arthur J. O'Dwyer

Well, it "works" without UB, although I don't think one would "expect"
long lines to be truncated :) I probably should have made some note
of that behavior in my original post.

See, that's what I mean when I say it *looks* like it's wrong. :D
Take a much closer look, and you'll find that long lines are *not*
truncated -- they're just output "piecewise" in multiple calls to
fgets/fputs (or printf; I forget which you used). So the output is
absolutely correct w.r.t. long lines -- but it's weird enough code
to fool me, and then to fool you!
I noted elsewhere that in any
case putc() is probably better regardless.

Definitely. Though you'll note I didn't get my code quite right
either. ;-)

-Arthur
 
C

Christopher Benson-Manica

Arthur J. O'Dwyer said:
See, that's what I mean when I say it *looks* like it's wrong. :D
Take a much closer look, and you'll find that long lines are *not*
truncated -- they're just output "piecewise" in multiple calls to
fgets/fputs (or printf; I forget which you used). So the output is
absolutely correct w.r.t. long lines -- but it's weird enough code
to fool me, and then to fool you!

So it is, on all counts. Would have looked smarter if I'd just kept
my mouth shut ;) Goes for both of us, perhaps...
 
C

CBFalconer

Christopher said:
Well, it "works" without UB, although I don't think one would
"expect" long lines to be truncated :) I probably should have
made some note of that behavior in my original post. I noted
elsewhere that in any case putc() is probably better regardless.

Look again. It doesn't even truncate long lines.
 
N

no_name

Advocated said:
Just been searching google, but havent come up with anything. Just
wondering, whats the best way to print say a file.txt or other format to the

You could use the following C program...

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

int main( int argc, char *argv[] )
{
char buf[256];
FILE *fp;

if( argc != 2 ) {
fprintf( stderr, "Usage: %s <filename>\n", argv[0] );
return EXIT_FAILURE;
}
if( (fp=fopen(argv[1],"r")) == NULL ) {
fprintf( stderr, "Could not open file \"%s\"\n", argv[1] );
return EXIT_FAILURE;
}
while( fgets(buf,sizeof buf,fp) ) {
printf( "%s", buf );
}
printf( "\n" ); /* in case there were no newlines in the file */
fclose( fp );
return EXIT_SUCCESS;
}

(salient comments from the regulars appreciated)

Where we have to use "clearerr()"?

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


#if !defined(BUFSIZ)
#define BUFSIZ 256
#endif


/* here sizeof(buf)== BUFSIZ */
size_t rread(FILE* fp, char* buf, size_t* err)
{static size_t contar=0, re=0;
size_t con;

contar += (con=fread(buf, 1, BUFSIZ, fp));
if(ferror(fp))
{if(!re) {*err=contar; re=1;}
clearerr(fp);
}
return con;
}


/* here sizeof(buf)== BUFSIZ */
size_t wwrite(FILE* fp, char* buf, size_t* err, size_t num)
{static size_t contaw=0, wr=0;
size_t con;

contaw += (con=fwrite(buf, 1, num, fp));
fflush(fp);
if(!wr && con!=num)
{*err=contaw; wr=1;}
return con;
}


int read_write(FILE* fin, FILE* fout) /* fin and fout must be
opened first */
{char buf[BUFSIZ];
size_t yr=0, yw=0, num;
int c;

if(fin==stdout || fout==stdin || fin==0 || fout==0)
return -1;
if(ferror(fin))
clearerr(fin);
if(ferror(fout))
clearerr(fout);
if(feof(fin))
return 1; /* no errors */
do{num=rread(fin, buf, &yr);
if(num)
{wwrite(fout, buf, &yw, num); c=buf[--num]; }
}while(!feof(fin));
if(fout==stdout && c!='\n') c=fputc('\n', fout);
fflush(fout);
if(yr) fprintf( stderr, "Error in reading from %lu char\n",
(unsigned long) yr);
if(yw) fprintf( stderr, "Error in writing from %lu char\n",
(unsigned long) yw);
if(c==-1) fprintf( stderr, "Error in writing the last \\n ");
return c==-1 ? 0 : !(yr+yw) ;
}

void ricor(int c, char** a)
{FILE *fp;
if(a==0 || c<=0 || a[c]==0) return;
if( (fp=fopen(a[c],"r")) == NULL )
{fprintf( stderr, "I could not open file \"%s\"\n", a[c] );
ricor(++c, a);
return;
}
fprintf( stderr, "I writing the file \"%s\": \n", a[c] );
read_write(fp, stdout);
fclose(fp);
ricor(++c, a);
}


int main( int argc, char *argv[] )
{if( argc < 2 )
{fprintf(
stderr, "Usage: %s <filename_0> <filename_1> ... <filename_n>\n",
argv[0]!=NULL ? argv[0]: "This program "
);
return EXIT_FAILURE;
}

ricor(1, argv);
return EXIT_SUCCESS;
}
 
N

no_name

Where we have to use "clearerr()"? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_________________________
#include <stdio.h>
#include <stdlib.h>


#if !defined(BUFSIZ)
#define BUFSIZ 256
#endif


/* here sizeof(buf)== BUFSIZ */
size_t rread(FILE* fp, char* buf, size_t* err)
{static size_t contar=0, re=0;
size_t con;

contar += (con=fread(buf, 1, BUFSIZ, fp));
if(ferror(fp))
{if(!re) {*err=contar; re=1;}
if(!re) {*err=contar-con; re=1;}
clearerr(fp);
}
return con;
}


/* here sizeof(buf)== BUFSIZ */
size_t wwrite(FILE* fp, char* buf, size_t* err, size_t num)
{static size_t contaw=0, wr=0;
size_t con;

contaw += (con=fwrite(buf, 1, num, fp));
fflush(fp);
if(!wr && con!=num)
{*err=contaw; wr=1;}
{*err=contaw-con; wr=1;}
 
C

Christopher Benson-Manica

Jeremy Yallop said:
If argc is 0 then argv[0] is a null pointer.

On common implementations (Unix, for example), this is never the case,
correct? Good call though.
Do you mean "sapient"?

A quick check of dictionary.com confirms that my vocabulary needs
work. I'm embarassed to say I've been misusing "salient" thus for
many years. ;(
 
A

Alexander Bartolich

begin followup to Christopher Benson-Manica:
Jeremy Yallop said:
If argc is 0 then argv[0] is a null pointer.

On common implementations (Unix, for example), this is never
the case, correct? Good call though.

It is very easy to set up.
Though only few programs can actually handle this.

#include <unistd.h>
int main(int argc, char** argv, char** env)
{
char* const arg[] = { 0 };
execve("/bin/sh", arg, env);
}
 

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
474,129
Messages
2,570,770
Members
47,329
Latest member
FidelRauch

Latest Threads

Top