success! I think

B

Bill Cunningham

your current problem seems almost identical to one I
gave a solution for. The only difference is the previous one
used fread/fwrite. I cannot comprehend how you can read my code

That's it right there. The ch you used I don't see all of what's going
on in your code. Basically I can't read it all.
Especially down around do.

and then post code that tries to copy a file ***without using a
loop construct***

***By Nick K.***

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

int main(void)
{
char buf [2048];
FILE *fp_in;
FILE *fp_out;
size_t ch_read;

if ((fp_in = fopen ("as.exe", "rb")) == NULL)
{
fprintf (stderr, "failed to open input file\n");
exit (EXIT_FAILURE);
}

if ((fp_out = fopen ("a.exe", "wb")) == NULL)
{
fprintf (stderr, "failed to open output file\n");
fclose (fp_in);
exit (EXIT_FAILURE);
}

do
{
if ((ch_read = fread (buf, 1, sizeof(buf), fp_in)) !=
sizeof(buf)
&& ferror(fp_in))
{
fprintf (stderr, "read error\n");
fclose (fp_in);
fclose (fp_out);
exit (EXIT_FAILURE);
}

if (fwrite (buf, 1, ch_read, fp_out) != ch_read)
{
fprintf (stderr, "write error\n");
fclose (fp_in);
fclose (fp_out);
exit (EXIT_FAILURE);
}
}
while (ch_read == sizeof(buf));

fclose (fp_in);
fclose (fp_out);

return 0;
}


----
do
{
if ((ch_read = fread (buf, 1, sizeof(buf), fp_in)) !=
sizeof(buf)
&& ferror(fp_in))
{

Here's where I get lost.

Bill
 
B

Bartc

Bill said:
That's it right there. The ch you used I don't see all of what's
going on in your code. Basically I can't read it all.
Especially down around do.
do
{
if ((ch_read = fread (buf, 1, sizeof(buf), fp_in)) !=
sizeof(buf)
&& ferror(fp_in))
{

Here's where I get lost.

Same here. Most of this is error-checking code that is not so important when
learning.

Without that error code, the main loop comes down to this, where I've
substituted N for sizeof(BUF):

do
{ ch_read = fread (buf, 1, N, fp_in);
fwrite (buf, 1, ch_read, fp_out);
}
while (ch_read == N);

This will read and write blocks of N characters, until either 0 characters
have been read, indicating end-of-file, or 1..N-1 characters have been read,
indicating this was the last (partial) block.

-- Bartc
 
N

Nick Keighley

Same here. Most of this is error-checking code that is not so important when
learning.
eek!


Without that error code, the main loop comes down to this, where I've
substituted N for sizeof(BUF):

    do
    {   ch_read = fread (buf, 1, N, fp_in);
        fwrite (buf, 1, ch_read, fp_out);
    }
    while (ch_read == N);

the original post had a piece of p-code
almost identical to the above.
 
N

Nick Keighley

your current problem seems almost identical to one I
gave a solution for. The only difference is the previous one
used fread/fwrite. I cannot comprehend how you can read my code

    That's it right there. The ch you used I don't see all of what's going
on in your code. Basically I can't read it all.
Especially down around do.

and then post code that tries to copy a file ***without using a
loop construct***

and I still don't understand why you tried to mange without a loop...
It doesn't have to be a do while (I'm not very fond of 'em)
but you do need a loop

***By Nick K.***

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

int main(void)
{
    char buf [2048];
    FILE *fp_in;
    FILE *fp_out;
    size_t ch_read;

    if ((fp_in = fopen ("as.exe", "rb")) == NULL)
    {
        fprintf (stderr, "failed to open input file\n");
        exit (EXIT_FAILURE);
    }

    if ((fp_out = fopen ("a.exe", "wb")) == NULL)
    {
        fprintf (stderr, "failed to open output file\n");
        fclose (fp_in);
        exit (EXIT_FAILURE);
    }

    do
    {
        if ((ch_read = fread (buf, 1, sizeof(buf), fp_in)) !=
sizeof(buf)
             &&  ferror(fp_in))
        {
            fprintf (stderr, "read error\n");
            fclose (fp_in);
            fclose (fp_out);
            exit (EXIT_FAILURE);
        }

        if (fwrite (buf, 1, ch_read, fp_out) != ch_read)
        {
            fprintf (stderr, "write error\n");
            fclose (fp_in);
            fclose (fp_out);
            exit (EXIT_FAILURE);
        }
    }
    while (ch_read == sizeof(buf));

    fclose (fp_in);
    fclose (fp_out);

    return 0;

}

----
 do
    {
        if ((ch_read = fread (buf, 1, sizeof(buf), fp_in)) !=
sizeof(buf)
             &&  ferror(fp_in))
        {

Here's where I get lost.

ok. I suppose assigning and testing all in one statement
is a bit Cish (though I'm not the onlt perpetrator!).

My code with the write taken out

do
{
if ((ch_read = fread (buf, 1, sizeof(buf), fp_in)) != sizeof(buf)
&& ferror(fp_in))
{
TERMINATE;
}
}
while (ch_read == sizeof(buf))


simplify the if

do
{
ch_read = fread (buf, 1, sizeof(buf), fp_in);

/* terminate the program if too few characters were read
and an error occurred. Note a "short" read could be
simply caused by getting to the end of the file and
that shouldn't be treated as an error */
if ((ch_read != sizeof(buf) && ferror(fp_in))
{
TERMINATE;
}
}
while (ch_read == sizeof(buf)); /* read until we get a short non-
error read */

is that clearer?

or this (no do-while)

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

int main(void)
{
char buf [2048];
FILE *fp_in;
FILE *fp_out;
size_t ch_read;

if ((fp_in = fopen ("as.exe", "rb")) == NULL)
{
fprintf (stderr, "failed to open input file\n");
exit (EXIT_FAILURE);
}

if ((fp_out = fopen ("a.exe", "wb")) == NULL)
{
fprintf (stderr, "failed to open output file\n");
fclose (fp_in);
exit (EXIT_FAILURE);
}

ch_read = sizeof(buf);
while (ch_read == sizeof(buf))
{
ch_read = fread (buf, 1, sizeof(buf), fp_in);

if ((ch_read != sizeof(buf) && ferror(fp_in))
{
fprintf (stderr, "read error\n");
fclose (fp_in);
fclose (fp_out);
exit (EXIT_FAILURE);
}

if (fwrite (buf, 1, ch_read, fp_out) != ch_read)
{
fprintf (stderr, "write error\n");
fclose (fp_in);
fclose (fp_out);
exit (EXIT_FAILURE);
}
}

fclose (fp_in);
fclose (fp_out);

return 0;
}


this makes an extra test
 
B

Bartc

Richard Heathfield said:
Bartc said:



I can't agree with that. If you postpone learning about error-checking
until you've learned everything else, you'll end up never learning about
it at all

OK, keep the extended checking for the next lesson then.

The essential checks are verifying the file handles, and checking for
end-of-file, and these are done here.

Other checks are for errors unlikely in a learning situation, but themselves
become essential if this code was put into a library function to be used in
many different circumstances.

Otherwise the code looks overwhelming.

Quote from K&R2 p.164: "Although output errors are rare, they do occur (for
example, if a disk fills up), so a production program should check this as
well". Note the word 'production'.
 
B

Bill Cunningham

Richard Heathfield said:
I can't agree with that. If you postpone learning about error-checking
until you've learned everything else, you'll end up never learning about
it at all - and this view is borne out by a huge amount of supposedly
professional code out there in the real world that completely ignores the
idea that anything might ever not quite work out the way the programmer
wants it to.
I haven't got to do and certainly not switch yet. But I'm getting pretty
good with for and using while without braces. A continuous loop with
basically two decsions. I learned how to open and close a file and use fread
fwrite simply at first without error checking. I knew error checking was
good needed to be learned too so that was the next step. After I was opening
and closing files and writing both binary and text (with fprintf). I added
error checking. Then tried for fgetc and that's where I am now. I personally
would have to agree with Bart. A person just needs to realize at the outset
they will need error checking in real life.

I had to conquer the open /write/close beast then the error checking and
I also notice most people don't use feof() but EOF.

Bill
 
B

Bill Cunningham

[snip]

is that clearer?

or this (no do-while)

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

int main(void)
{
char buf [2048];
FILE *fp_in;
FILE *fp_out;
size_t ch_read;

if ((fp_in = fopen ("as.exe", "rb")) == NULL)
{
fprintf (stderr, "failed to open input file\n");
exit (EXIT_FAILURE);
}

if ((fp_out = fopen ("a.exe", "wb")) == NULL)
{
fprintf (stderr, "failed to open output file\n");
fclose (fp_in);
exit (EXIT_FAILURE);
}

ch_read = sizeof(buf);
while (ch_read == sizeof(buf))
{
ch_read = fread (buf, 1, sizeof(buf), fp_in);

if ((ch_read != sizeof(buf) && ferror(fp_in))
{
fprintf (stderr, "read error\n");
fclose (fp_in);
fclose (fp_out);
exit (EXIT_FAILURE);
}

if (fwrite (buf, 1, ch_read, fp_out) != ch_read)
{
fprintf (stderr, "write error\n");
fclose (fp_in);
fclose (fp_out);
exit (EXIT_FAILURE);
}
}

fclose (fp_in);
fclose (fp_out);

return 0;
}


this makes an extra test


That's the way I learned yes that's great! Except I didn't learn with the
while braces that seems to be an option and the sequential reading makes for
good error check I've found out. I use return -1 instead of the exit
macros.

Bill
 
B

Bill Cunningham

I put together this code that seems to work great by studying your code
and other code I have saved and been studying .

#include <stdio.h>

int main(int argc, char *argv[]) {
FILE *ifp,*ofp;
int a;
if(argc!=3) {
fprintf(stderr,"usage error\n");
return -1;
}
ifp=fopen(argv[1],"rb");
if (ifp==0) {
fprintf(stderr,"input error\n");
return -1;
}
ofp=fopen(argv[2],"wb");
if (ofp==0) {
fprintf(stderr,"output error\n");
return -1;
}
while((a=fgetc(ifp))!=EOF)
fputc(a,ofp);
fclose(ifp);
fclose(ofp);
printf("done\n");
return 0;
}

A little less overhead without stdlib and using return -1 if that really
matters. It seems to work like cp.

Bill
 
B

Barry Schwarz

[snip]

is that clearer?

or this (no do-while)

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

int main(void)
{
char buf [2048];
FILE *fp_in;
FILE *fp_out;
size_t ch_read;

if ((fp_in = fopen ("as.exe", "rb")) == NULL)
{
fprintf (stderr, "failed to open input file\n");
exit (EXIT_FAILURE);
}

if ((fp_out = fopen ("a.exe", "wb")) == NULL)
{
fprintf (stderr, "failed to open output file\n");
fclose (fp_in);
exit (EXIT_FAILURE);
}

ch_read = sizeof(buf);
while (ch_read == sizeof(buf))
{
ch_read = fread (buf, 1, sizeof(buf), fp_in);

if ((ch_read != sizeof(buf) && ferror(fp_in))

You don't need the first test. If ferror returns a non-zero value, an
error occurred regardless of how many bytes were read in.
{
fprintf (stderr, "read error\n");
fclose (fp_in);
fclose (fp_out);
exit (EXIT_FAILURE);
}

if (fwrite (buf, 1, ch_read, fp_out) != ch_read)
{
fprintf (stderr, "write error\n");
fclose (fp_in);
fclose (fp_out);
exit (EXIT_FAILURE);
}
}

fclose (fp_in);
fclose (fp_out);

return 0;
}


Remove del for email
 

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

Similar Threads

Working with files 1
Remove repeated words from a file 3
program bug 29
I have a problem in my study 25
How to set Control-L as variable 6
creating a testfile for catv 10
Problem with realloc (I think) 11
comparison error 12

Members online

No members online now.

Forum statistics

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

Latest Threads

Top