I’ve written this program:
#include <stdio.h>
#include <stdlib.h>
int concatenate(int argc, char *argv[]);
int main(int argc, char *argv[]) {
concatenate(argc, argv);
return 0;
}
int concatenate(int argc, char *argv[]) {
FILE *temp;
int sz;
for (int i = 1; i < argc; i++) {
if ((temp = fopen(argv[i], "r")) == NULL) {
fprintf(stderr, "Error while opening file %s", argv[i]);
exit(EXIT_FAILURE);
}
fseek(temp, 0L, SEEK_END);
sz = ftell(temp);
rewind(temp);
fwrite(stdout, 1, sz, temp);
fclose(temp);
}
}
And I want to know why the program is printing rare characters to stdout
and how to solve the problem to no prevent to commit it in the future. Thank you in advance.
By the way, I’m passing normal .txt files to the program and I’m currently working on Ubuntu.
2
Answers
The program has undefined behavior here:
The prototype for
fwrite
is:Your call attempts to write to the stream pointed to by
temp
a number of bytes equal to1 * sz
pointed to bystdout
.Writing to a stream open for reading has undefined behavior. It is unlikely, although not impossible, that this call outputs anything to
stdout
. Maybe you tried a different parameter order such asfwrite(temp, 1, sz, stdout)
which attempts to outputsz
bytes from the contents of theFILE
structure pointed to bytemp
tostdout
and would show bizarre output if anything at all.There might not be
sz
bytes accessible via theFILE
pointer. As a matter of fact,FILE *
are opaque pointers; theFILE
type may be an incomplete type without an actual definition, so no actual bytes may be readable at that address. Reading bytes fromstdout
has undefined behavior.Even
sz = ftell(temp)
does not produce a reliable result as the stream was opened in text mode. On Unix systems, this would evaluate to the file length in bytes, but on legacy systems with obscure text file handling, the result can only be passed tofseek()
withSEEK_SET
mode for later repositioning; its numerical value is meaningless.Here is a modified version:
The problem is here:
probably what you want is:
fwrite
will print the binary representation of the data you pass to it (and you also pass it incorrectly, not as a pointer reference)That will print the files sizes to
stdout
which is what you apparently do in your code. Despite of the call being calledconcatenate()
this is something strange and probably has directed other colleagues to show you how to concatenate files. You need to explain a bit more. Please, edit your question to clarify.