LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   fread and fwrite seem to only work when using text files and not with jpgs (https://www.linuxquestions.org/questions/programming-9/fread-and-fwrite-seem-to-only-work-when-using-text-files-and-not-with-jpgs-4175532835/)

retroCheck 02-02-2015 01:30 PM

fread and fwrite seem to only work when using text files and not with jpgs
 
Using fopen,fwrite doesn't seem to work with jpegs.

fedex.jpg and mypic.jpg should be the same size -

-rw-rw-rw- 1 student student 29171 Jan 5 19:09 fedex.jpg
-rw-rw-r-- 1 student student 4 Feb 2 11:04 mypic.jpg

Code:

 
  1 #include <sys/stat.h>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <time.h>
  5 #include <errno.h>
  6 #include <iostream>
  7 #include <string.h>
  8 #include <utime.h>
  9
 10 using namespace std;
 11 FILE *fp;
 12 FILE *fp2;
 13 char readF[2000000];
 14 int main(int argc, char **argv){
 15        fp = fopen(argv[1],"ab+");
 16        fread(readF,2000000,1,fp);
 17        printf("%s",readF);
 18        fp2 = fopen(argv[2],"rb+");
 19        fwrite(&readF,strlen(readF),1,fp2);
 20 }


suicidaleggroll 02-02-2015 01:37 PM

jpg is binary, yet you're printing it with %s and getting the length for the write with strlen. Also, you're opening the source file with "a" which means append, and opening the destination file with "r" which means read.

You can't use %s and strlen for blocks of binary. All it takes is a null byte in the data block and everything stops (or worse yet, no null byte and you blow through the end of your array and out into undefined memory).

Swap your a/r in the opens (assuming you do want to append, which you probably don't...use "w" to overwrite), print it with %x for hex, and use the output of your fread to get the number of bytes read to use in your print and write.

smallpond 02-02-2015 02:37 PM

Also, why use global variables for fp, fp2 and readF? fp and fp2 should be local automatics. A large allocation like readF should come from the heap using new to avoid the C++ global initialization code.

NevemTeve 02-03-2015 12:44 AM

printf and strlen aren't used in this context. Use fwrite(stdout) and the return value of the previous fread. (Generally, return values aren't meant to be ignored.)

veerain 02-03-2015 07:12 AM

You should read 'I/O on Streams' topic from info page of libc,

Code:

info libc

sundialsvcs 02-03-2015 08:56 AM

You should be using fread() to read a chunk of the file into a buffer, then fwrite() to another file from that buffer, and doing the whole thing in a loop that repeats until there are no more bytes to be read. The information is binary, not null-terminated strings.

rtmistler 02-03-2015 12:14 PM

You don't need the printf(), instead get the return from the fread() to see how many bytes you read, then use readF for the fwrite and the return value from the fread as the size. Omit the printf() statement entirely.

sundialsvcs 02-03-2015 12:40 PM

Indeed. "printf()" with the "%s" format-specifier will interpret the variable as being a zero-terminated string, which it emphatically is not.

You are moving bytes around. You're not looking at those bytes.

multiplex22 02-04-2015 01:14 PM

You have to fclose to finish the write. + means to create and trucate if non existent. Useless on reads. R is read, w is is write. B is binary and not always relevant. Try man 2 fread for more info about the fio functions.


[/B]
Quote:

Originally Posted by retroCheck (Post 5310711)
Using fopen,fwrite doesn't seem to work with jpegs.

fedex.jpg and mypic.jpg should be the same size -

-rw-rw-rw- 1 student student 29171 Jan 5 19:09 fedex.jpg
-rw-rw-r-- 1 student student 4 Feb 2 11:04 mypic.jpg

Code:

 
  1 #include <sys/stat.h>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <time.h>
  5 #include <errno.h>
  6 #include <iostream>
  7 #include <string.h>
  8 #include <utime.h>
  9
 10 using namespace std;
 11 FILE *fp;
 12 FILE *fp2;
 13 char readF[2000000];
 14 int main(int argc, char **argv){
 15        fp = fopen(argv[1],"ab+");
 16        fread(readF,2000000,1,fp);
 17        printf("%s",readF);
 18        fp2 = fopen(argv[2],"rb+");
 19        fwrite(&readF,strlen(readF),1,fp2);
 20 }



multiplex22 02-04-2015 01:17 PM

Quote:

Originally Posted by multiplex22 (Post 5312037)
You have to fclose to finish the write. + means to create and trucate if non existent. Useless on reads. R is read, w is is write. B is binary and not always relevant. Try man 2 fread for more info about the fio functions.


[/B]

Also noted you are using strlen for the size. Wrong for binaries. You need the absolute size using stat, not the text calculated size. Try man stat as well.

NevemTeve 02-05-2015 05:23 AM

Note: "a+" means append and read, "r+" means read and write.


All times are GMT -5. The time now is 05:56 AM.