In the integrated development environment of Windows (Qt, VC, VS all have this problem), write the C/C + + program about file reading. When it reads 0X1A, it ends unexpectedly. After debugging and checking, it is found that 0X1A is processed as 0XFF (EOF (- 1)) after reading, but there is no such problem of parsing error in Linux (tested in RedHat 6.4 and Ubuntu 14.04). For the reasons of this problem, please refer to: https://blog.csdn.net/zhoubl668/article/details/7054282 . Then there are two solutions:
1. Read in binary mode:
FILE * fp = fopen("file", "rb");//Read as binary stream
Take the file parsing of ". DCM" as an example (the information of new.dcm is parsed into hexadecimal and output to new.hex):
/*
* 2018 April 20, 2016 16:37:10
* Binary stream reading
*
*/
#include "stdafx.h"
#define STRING_BUFFER 16
char strbuf[STRING_BUFFER] = {0};
int main(void)
{
size_t i = 0;
FILE * fpr = fopen("F:\\new.dcm", "rb");//Read as binary stream
FILE * fpw = fopen("F:\\new.hex", "w");//output file
if(fpr == NULL || fpw == NULL){
printf("open file failure at line:%d\n", __LINE__);
exit(EXIT_FAILURE);
}
fprintf(fpw, "%08X: ", num);
while(!feof(fpr)){//It can be judged directly by feof()
unsigned char ch = fgetc(fpr);//Read one character at a time
strbuf[num % STRING_BUFFER] = ch;//And record it in a 16 character line buffer
fprintf(fpw, "%02X ", ch);//Write the character (1Byte, such as' A ') to the output file (change to 2byte, and' A 'corresponds to 0X41)
num++;//Number of characters read plus 1
if(num % 16 == 0){//Output file format, read 16 bytes and change to another line
fprintf(fpw, "; ");
for(i = 0; i<STRING_BUFFER; i++){//Resolve characters in buffer
if(strbuf[i] > 31 && strbuf[i] < 127)
fprintf(fpw, "%c", strbuf[i]);
else
fprintf(fpw, ".");
}
fprintf(fpw, "\n%08X: ", num);//Line feed
memset(strbuf, 0, STRING_BUFFER);//Clear buffer
}
}
fclose(fpr);
fclose(fpw);
printf("Complete!\n");
return 0;
}
2. Determine whether the EOF (0XFF) encountered by file reading is caused by 0X1A or to the end of the file:
FILE * fp = fopen("file", "r");//Read as text file
fseek(fp, 0, SEEK_END);
const size_t len_file = ftell(fp);
fseek(fp, 0, SEEK_SET);
//After obtaining the length of the file, judge whether to end according to the number of characters read
Also read the above file:
#include "stdafx.h"
#define STRING_BUFFER 16
char strbuf[STRING_BUFFER] = {0};
int main(void)
{
size_t num = 0, i = 0;
FILE * fpr = fopen("F:\\new.dcm", "r");//Read as non binary stream
FILE * fpw = fopen("F:\\new.hex", "w");
if(fpr == NULL || fpw == NULL){
printf("open file failure at line:%d\n", __LINE__);
exit(EXIT_FAILURE);
}
//Get file length
fseek(fpr, 0, SEEK_END);
const size_t len_file = ftell(fpr);
fseek(fpr, 0, SEEK_SET);
printf("%d\n", len_file);
fprintf(fpw, "%08X: ", num);
//feof() cannot be used to judge, because 0X1A has been resolved to 0XFF when reading in text form
while(num < len_file){//Determine whether to reach the end of the file according to the number of characters read and the length of the file
unsigned char ch = fgetc(fpr);
if((unsigned char)ch == 0XFF){//If 0XFF is read, judge whether it is caused by 0X1A
strbuf[num % STRING_BUFFER] = 0X1A;
fprintf(fpw, "1A ");
fseek(fpr, num+1, SEEK_SET);
//Fseek (FPR, 1, seek ﹣ cur) or fseek (FPR, fTell (FPR) + 1, seek ﹣ set) cannot be used;
//Because if the end character EOF or 0X1A is encountered, the value of ftell(), that is, seek UU cur, will become a multiple of 4096
}
else{
strbuf[num % STRING_BUFFER] = ch;
fprintf(fpw, "%02X ", ch);
}
num++;
if(num % 16 == 0){
fprintf(fpw, "; ");
for(i = 0; i<STRING_BUFFER; i++){
if(strbuf[i] > 31 && strbuf[i] < 127)
fprintf(fpw, "%c", strbuf[i]);
else
fprintf(fpw, ".");
}
fprintf(fpw, "\n%08X: ", num);
memset(strbuf, 0, STRING_BUFFER);
}
}
fclose(fpr);
fclose(fpw);
printf("Complete!\n");
return 0;
}