I have a C program that creates a binary file from a text file.
/*makeBinry.c*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char *argv[]){
char *ptext, *btext="file.bin";
if(argc != 2){
printf("Using default \"text.txt\" file to create mnemonics table\n");
ptext = "text.txt";
}else{
ptext = argv[2];
}
FILE *fp, *fb;
if(!(fp=fopen(ptext, "r"))){
fprintf(stdout, "Error: File %s is not available\n", ptext);
exit(1);
}
if(!(fb = fopen(btext, "wb"))){
fprintf(stdout, "Error: File %s is cannot be opened to write\n", btext);
exit(1);
}
int i, j, k;
char s[8], c, stringed[20];
while(!feof(fp)){
memset(stringed, '\0', sizeof(stringed));
fscanf(fp, "%X %d %c %d %[^\n]s", &i, &j, &c, &k, s);
sprintf(stringed, "%X %d %c %d %[^\n]s", &i, &j, &c, &k, s);
fwrite(stringed, 1, strlen(stringed), fb);
}
fprintf(stdout, "Success: %s file successfully created\n", btext);
fclose(fp);
fclose(fb);
return 0;
}
I have another program that reads the data in the binary file and stores into an array.
/*mainProg.c*/
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
typedef struct opStruct{
int hexv, fv, kv;
char str[8], key;
} node;
node* makeTable(char *filename){
FILE *fp;
if(!(fp = fopen(filename, "rb"))){
fprintf(stdout, "Error: Unable to open file %s\n", filename);
exit(1);
}
int hv, fv, kv;
char s[8], c, str[20];
while(!(feof(fp))){
sscanf(fp,"%X %d %c %d %[^\n]s", &hv, &fv, &c, &kv, str);
fprintf(stdout, "%X %d %c %d %s", hv, fv, c, kv, str);
}
fclose(fp);
return NULL;
}
int main(){
int i;
char *filename = "file.bin";
node *t_table = makeTable(filename);
return 0;
}
When I run the mainProg.c
the program goes into an infinite loop. I figured it is because fp
is never increased. How could I increase the file pointer and still use sscanf
to read the binary file in the formatted manner? I'm not allowed to use fread()
. Since currently, I'm not creating the table the function makeTable
returns NULL
.
Also, since the number of lines in the binary file would be unknown, how can I create the array dynamically using realloc
?
the following code
fscanf()
rather than the faulty feof()
perror()
so system error message is displayed on stderrerror checking for the calls to fwrite(), fclose() could be added but they are VERY unlikely to produce an error
and now the code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct record
{
unsigned int hv;
int fv;
int kv;
char c;
char s[8];
};
int main(int argc, char *argv[])
{
char *ptext, *btext="file.bin";
if(argc != 2)
{
printf("Using default \"text.txt\" file to create mnemonics table\n");
ptext = "text.txt";
}
else
{
ptext = argv[1];
}
FILE *fp;
FILE *fb;
if(!(fp=fopen(ptext, "r")))
{
perror( "fopen for read of text file failed" );
fprintf(stdout, "Error: File %s is not available\n", ptext);
exit(1);
}
if(!(fb = fopen(btext, "wb")))
{
perror( "fopen for write of binary file failed" );
fprintf(stdout, "Error: File %s is cannot be opened to write\n", btext);
fclose( fp ); // cleanup
exit(1);
}
struct record myRecord;
// produce binary file from text input
// note: leading space in format string, to consume any left over newline, etc
while(5 == fscanf(fp, " %X %d %c %d %7[^\n]",
&myRecord.hv,
&myRecord.fv,
&myRecord.c,
&myRecord.kv,
myRecord.s) )
{
fwrite( &myRecord, sizeof myRecord, 1, fb );
}
fprintf(stdout, "Success: %s file successfully created\n", btext);
fclose(fp);
fclose(fb);
return 0;
}
/*mainProg.c*/
#include <stdio.h>
#include <stdlib.h>
//#include <malloc.h>
#include <string.h>
//typedef struct opStruct
//{
// int hexv, fv, kv;
// char str[8], key;
//} node;
struct record
{
unsigned int hv;
int fv;
int kv;
char c;
char s[8];
};
//node* makeTable(char *filename)
void makeTable( char *filename )
{
FILE *fp;
if(!(fp = fopen(filename, "rb")))
{
fprintf(stdout, "Error: Unable to open file %s\n", filename);
exit(1);
}
// implied else, fopen successful
struct record myRecord;
// use fscanf() not sscanf()
while( fread( &myRecord, sizeof myRecord, 1, fp) )
{
//sprintf( , "%X %d %c %d %s\n" hv, fv, c, kv, s );
//fprintf(stdout, "%s", str );
fprintf( stdout, "\n%X", myRecord.hv );
fprintf( stdout, " %d", myRecord.fv );
fprintf( stdout, " %c", myRecord.c );
fprintf( stdout, " %d", myRecord.kv );
fprintf( stdout, " %8.8s", myRecord.s );
}
fprintf( stdout, "\n" ); // force flush
fclose(fp);
//return NULL;
} // end function: makeTable
int main( void )
{
//int i;
char *filename = "file.bin";
//node *t_table = makeTable(filename); // raises compiler warning about unused variable
makeTable(filename);
return 0;
} // end function: main