0

I made a code:

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

int main (int argc, char * argv[]) // taking files
{
    FILE * fp;
    FILE * fp2;
    int c;
.
. // checking possible problems
.
    while ( (c = fgetc(fp)) != EOF){ // copying one file to another one
        fputc (c, stdout);
        fputc (c, fp2);
    }

    fclose(fp);
    fclose(fp2);
    fp = NULL;
    fp2 = NULL;

    return EXIT_SUCCESS;
}

I would ask you, if is it possible to make the same while statement with use of fgets function instead of fgetc- like:

fgets(fp, sizeof(fp), stdin));
1
  • Note that since you have FILE *fp;, your example fgets(fp, sizeof(fp), stdin) would be wholly inappropriate, even though it would compile — C is not a type-safe language at times. You want char buffer[4096]; and fgets(buffer, sizeof(buffer), stdin) (or use fp instead of stdin if you're reading from a file instead). Commented Nov 20, 2018 at 22:41

2 Answers 2

1

Yes, it's possible to use fgets() and fputs(). If you're using POSIX systems, you might find getline() better than fgets(), but you'd still use fputs() with it. Or you might find fread() and fwrite() appropriate instead. All of those work on arrays — you get to choose the size, you'd likely be using 4096 bytes as a buffer size.

For example:

char buffer[4096];
while (fgets(buffer, sizeof(buffer), fp) != NULL)
{
    fputs(buffer, stdout);
    fputs(buffer, fp2);
}

Or:

char buffer[4096];
size_t nbytes;
while ((nbytes = fread(buffer, sizeof(char), sizeof(buffer), fp)) > 0)
{
    fwrite(buffer, sizeof(char), nbytes, stdout);
    fwrite(buffer, sizeof(char), nbytes, fp2);
}

Warning: uncompiled code.

Note that in theory you should test that the fwrite() operations worked OK (no short writes). Production quality code would do that. You should also check that the fputs() operations succeed too.

Note that as hinted at by user2357112, the original code will work with arbitrary binary files (containing null bytes '\0') quite happily (though stdout may be less happy with it). Using fread() and fwrite() will work perfectly with binary files, and the only issue with text files is that they'd ignore newlines and write blocks of text as they're read (which is not usually an actual problem).

Sign up to request clarification or add additional context in comments.

2 Comments

Isn't the fgets version also going to have issues with null bytes in the input?
@user2357112: yes — it is. If you copy binary data with text functions, you get what you get. If the copying is for arbitrary files, then fread() and fwrite() are appropriate because they handle nulls fine. One problem with fgets() is that it does not tell you how many bytes it read, so if you read a line and the newline is missing, it could be because there was a null byte in the input. But there's no way to know. The getline() function reports how many bytes were read; you could use fwrite() to ensure that those bytes are all written. There are issues with getline(), too.
0

Yes, it is possible to write this program using fgets() and fputs(). We know that fgets() stops reading after encountering a newline or EOF, we can use this property but in this case, we can't directly use feof() function, else, we can use two file pointers and do something like this:

//after opening the file<*fp> to be read from in "r" mode and the file<*fp1> to be written to in "w" mode.

while(1){
if(fgetc(fp)!=EOF) fseek(fp,-1,1);
else break;
fgets(buff,100,fp);
fputs(buff,fp1);}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.