I am working on a project where I need to read data from a binary file. I am trying to store the data into a char buffer. Suppose the binary file consisted of a character, an int and a double what size would the char buffer need to be ? And how would I convert back into int's and doubles ?
I am reading the data into a char buffer because it would improve the speed of my program.
Thanks!
The following example program fread()s the first DATASIZE sets of a char, an int and a float from a file specified on the command line:
typedef struct Data_s {
char c;
int i;
float f;
} Data_t;
#define DATASIZE 3
int main(int argc, char ** argv) {
if (1 >= argc) {
fprintf(stderr, "usage: %s <file name>\n", argv[0]);
return EXIT_SUCCESS;
}
{
FILE * f = fopen(argv[1], "r");
if (!f) {
perror("fopen() failed.");
return EXIT_FAILURE;
}
{
Data_t data[DATASIZE];
size_t sizeData = sizeof(*data);
size_t sizeToRead = sizeof(data)/sizeData;
memset(data, 0, sizeToRead * sizeData);
size_t sizeRead = fread(&data, sizeData, sizeToRead, f);
if (0 != fclose(f))
perror("fclose() failed,");
if (sizeToRead != sizeRead) {
perror("fread() failed.");
return EXIT_FAILURE;
}
for (size_t i = 0; i < sizeToRead; ++ i)
printf("read c=0x%02hhx, i=%d, f=%f from '%s'\n", data[i].c, data[i].i, data[i].f, argv[1]);
}
}
return EXIT_SUCCESS;
}
You can use the fscanf function to read the data from the file straight into eagerly awaiting variables:
char c;
int i;
double d;
FILE *fp = fopen("C:\\example.txt", "rb");
if (fp)
{
fscanf(fp, "%c%d%lf", &c, &i, &d);
fclose(fp);
printf("Character: %c\nInteger: %d\nDouble: %lf\n", c, i, d);
}
EDIT: If you're looking for more info on fscanf, see here
EDIT2: Binary Solution
FILE *fp = fopen("C:\\example.txt", "rb");
if (fp)
{
char buffer[sizeof(int) + sizeof(double) + sizeof(char)];
if (fread(buffer, 1, sizeof(buffer), fp) == sizeof(buffer))
{
char c = *(char*)buffer;
int i = *(int*)(buffer + sizeof(char));
double d = *(double*)(buffer + sizeof(char) + sizeof(int));
}
fclose(fp);
}
Related
I am trying to read the contents of a file and copy those contents into a string which has dynamic memory. However my program keeps allocating only 8 bytes to x. Ultimately I'm trying to create a general function that can read contents from a file and then return the contents as a char. Any help is appreciated.
char* readFile(unsigned long size, char *fileName) {
FILE *file = fopen(fileName, "r");
int c;
if(file != NULL)
{
while(c != EOF){ //calculate size of file
c = fgetc(file); //store character
size++;
}
char *x = (char *)malloc((size) * (sizeof(char))); // Size of x = 8 and I'm not sure why
rewind(file);
printf("\n");
int i = 0;
while(size - 1 > i){ //Reading the files contents to the allocated string
c = fgetc(file); //store character
if(c == EOF){
break;
}
x[i] = c;
i++;
}
fclose(file);
printf("Done Reading");
}
else
{
printf("\nError: Unable to open the file for Reading.\n");
}
rewind(file);
return 0;
}
I get a segmentation fault when I run
char* str = readFile(size, originalFile);
I would use stat to first get the size of your file
stat() retrieves information about the file pointed
to by pathname;
And then I made some tiny modifications to your function to make it work:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
char* readFile(char *fileName) {
FILE *file;
struct stat st;
if (!(file = fopen(fileName, "r")))
return NULL;
stat(fileName, &st);
unsigned long size = st.st_size;
char *x;
if (!(x = (char *)malloc((size + 1) * (sizeof(char))))) // Size of x = 8 and I'm not sure why
return NULL;
unsigned long i = 0;
while (i < size) //Reading the files contents to the allocated string
x[i++] = getc(file);
x[i] = '\0';
fclose(file);
printf("Done Reading\n");
return x;
}
int main(void) {
char *fileName = "a.txt";
char *res = readFile(fileName);
printf("%s\n", res);
return 0;
}
Don't forget that in C strings are NULL terminated, you need to malloc size+1 to add the final '\0'.
This is (IMHO) an easier way to find the size of the file:
char *readFile(const char *fileName)
{
unsigned long size = 0;
char *x;
FILE *file = fopen(fileName, "r");
int c;
if (file != NULL)
{
fseek(file, 0, SEEK_END); /* SET the position at EOF */
size = ftell(file); /* Record the position at EOF to return size of file */
rewind(file); /* SET position back to Origin */
printf("size detected %ld\n", size); // reads correct size
x = (char *)malloc((size) * (sizeof(char)));
rewind(file);
printf("\n");
int i = 0;
while (size - 1 > i)
{ //Reading the files contents to the allocated string
c = fgetc(file); //store character
if (c == EOF)
{
break;
}
x[i] = c;
i++;
}
fclose(file);
printf("Done Reading\n");
}
else
{
printf("\nError: Unable to open the file for Reading.\n");
return NULL;
}
rewind(file);
return x; // * you need to return x not zero
}
Successfully reads the content of the file:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *data;
data = readFile("records.txt");
printf("%s\n", data);
return 0;
}
I am writing a program to compare two binary files and plot the first difference. I want to read 16 bytes of data from each file continuously and compare them. For that I am storing 16 bytes from both file into char *buffer1, buffer2. When I print the output I am getting that buffer1 has both the data of file1 and file2.
The code is as follows:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void printConversion(char *buf1, char *buf2) {
size_t len = strlen(buf1);
char *binary = malloc(len * 8 + 1);
binary[0] = '\0';
for (size_t i = 0; i < len; ++i) {
char ch = buf1[i];
for (int j = 7; j >= 0; --j) {
if (ch & (1 << j)) {
strcat(binary,"1");
} else {
strcat(binary,"0");
}
}
}
printf("File1: %s\t", binary);
free(binary);
printf("File2:");
for (int i = 0; i < sizeof(buf2); i++) {
printf("%x", buf2[i] - '0');
}
}
void fileRead(FILE *fp, char *buf, int count) {
fseek(fp, count, SEEK_SET);
fread(buf, 1, 16, fp);
}
int fileSize(FILE *fp) {
fseek(fp, 0, SEEK_END);
int size = ftell(fp) + 1;
return size;
}
int main(int argc, char *argv[]) {
printf("***Binary File Comparator***\n ");
int count = 0;
int index = 0;
char buffer1[16];
char buffer2[16];
char buffer3[16];
char buffer4[16];
// Invalid Number of Arguments
if (argc < 3 || argc > 3) {
printf("Invalid Number of Arguments\n");
}
FILE *fp1, *fp2;
fp1 = fopen(argv[1], "rb");
int size = fileSize(fp1);
int size1 = size;
fclose(fp1);
while (size > 1) {
fp1 = fopen(argv[1], "rb");
fileRead(fp1, buffer1, count);
fclose(fp1);
fp2 = fopen(argv[2], "rb");
fileRead(fp2, buffer2, count);
if (size1 < count) {
int lastSize = count - size1;
count = count + lastSize;
fclose(fp2);
} else {
count = count+16;
fclose(fp2);
}
**printf("buffer1:%s\tbuffer2:%s\n", buffer1, buffer2)**;
size = size - 16;
int result = strcmp(buffer1, buffer2);
if (result != 0) {
for (int i = 0; i < sizeof(buffer1); i++) {
if (buffer1[i] != buffer2[i]) {
int count1 = (count - 16) + i;
index++;
if (index == 1) {
printf("Byte_Offset:%x\n", count1);
fp1 = fopen(argv[1], "rb");
fileRead(fp1, buffer3, count1);
fclose(fp1);
fp2 = fopen(argv[2], "rb");
fileRead(fp2, buffer4, count1);
fclose(fp2);
printConversion(buffer3, buffer4);
break;
}
} else {
continue;
}
}
}
}
}
I have tried to highlight the printf part that is printing my buffer1 and buffer2
The output is as follows:
buffer1:83867715933586928386771593358692 buffer2:8386771593358692
buffer1:49216227905963264921622790596326 buffer2:4921622790596326
buffer1:40267236116867294026723611686729 buffer2:4026723611686729
buffer1:82306223673529228230622367352922 buffer2:8230622367352922
buffer1:25869679356114222586967935611422 buffer2:2586967935611422
Can anybody help what I am doing wrong. Please point me the error and what optimization changes could be done in code. I am at learning stage your feedback will be very helpful.
You are complicating the task by reading 16 bytes at a time. If the goal is to indicate the first difference, just read one byte at a time from both files with getc() this way:
int compare_files(FILE *fp1, FILE *fp2) {
unsigned long pos;
int c1, c2;
for (pos = 0;; pos++) {
c1 = getc(fp1);
c2 = getc(fp2);
if (c1 != c2 || c1 == EOF)
break;
}
if (c1 == c2) {
printf("files are identical and have %lu bytes\n", pos);
return 0; // files are identical
} else
if (c1 == EOF) {
printf("file1 is included in file2, the first %lu bytes are identical\n", pos);
return 1;
} else
if (c2 == EOF) {
printf("file2 is included in file1, the first %lu bytes are identical\n", pos);
return 2;
} else {
printf("file1 and file2 differ at position %lu: 0x%02X <> 0x%02X\n", pos, c1, c2);
return 3;
}
}
In terms of efficiency, reading one byte at a time does not pose a problem if the streams are buffered. For large files, you can get better performance by memory mapping the file contents if available on the target system and for the given input streams.
Not an actual answer, but a word on optimisation. You can increase the speed of the program if you have a bigger buffer. Basically the larger the buffer the faster the program runs HOWEVER the speed you gain from just making it larger will increase logarithmically.
Here is a picture of a graph that will help you understand. Also, what i mentioned applies to any simmilar situation. This includes: Copying files, filling the sound buffer etc. Loading the entire file in your RAM first and operationg on it will usually be faster than loading parts of it. Ofc this is not possible with larger files but still this is what you should aim for if you want speed.
PS: I'm writting here because i don't have rep to comment.
EDIT: I came up with solution but since you did not state what you need to do with your buffer3 and buffer4 i packed it up inside a function.
If you are sure that you are only going to use 16 bytes as a buffer size, remove the nBufferSize parameter and replace the buffer dynamic allocation with a static one.
If after the execution you need the buffers, add them as parameters and keep the nBufferSize param. Keep in mind that if you intend to use them outside the function, you should also allocate them outside the function, so things don't get messy.
/** Returns 0 if files are identical, 1 if they are different and -1 if there
is an error. */
int FileCmp(char* szFile1, char* szFile2, int nBufferSize)
{
FILE *f1, *f2;
f1 = fopen(szFile1, "rb");
f2 = fopen(szFile2, "rb");
// Some error checking?
if (f1 == NULL || f2 == NULL)
return -1;
// You can check here for file sizes before you start comparing them.
// ...
// Start the comparrison.
/// Replace this part with static allocation. --------
char* lpBuffer1 = malloc(sizeof(char)*nBufferSize);
if (lpBuffer1 == NULL) // close the files and return error.
{
fclose(f1);
fclose(f2);
return -1;
}
char* lpBuffer2 = malloc(sizeof(char)*nBufferSize);
if (lpBuffer2 == NULL) // close the files, free buffer1 and return error.
{
free(lpBuffer1);
fclose(f1);
fclose(f2);
return -1;
}
/// --------------------------------------------------
while(1)
{
unsigned int uRead1 = fread(lpBuffer1, sizeof(char), nBufferSize, f1);
unsigned int uRead2 = fread(lpBuffer2, sizeof(char), nBufferSize, f2);
if (uRead1 != uRead2)
goto lFilesAreDifferent;
for(unsigned int i = 0; i < uRead1; i++)
if (lpBuffer1[i] != lpBuffer2[i])
goto lFilesAreDifferent;
if ((feof(f1) != 0) && (feof(f2) != 0))
break; // both files have nothing more to read and are identical.
goto lSkip;
lFilesAreDifferent:
free(lpBuffer1);
free(lpBuffer2);
fclose(f1);
fclose(f2);
return 1;
lSkip:;
}
// The files are the same. Close them, free the buffers and return 0.
free(lpBuffer1);
free(lpBuffer2);
fclose(f1);
fclose(f2);
return 0;
}
A simple Demo:
#define BUFFER_SIZE 16
int main(int nArgs, char** szArgs)
{
if (nArgs != 3)
{
printf("Invalid number of arguments.");
return 0;
}
int nResult = FileCmp(szArgs[1], szArgs[2], BUFFER_SIZE);
switch (nResult)
{
case 0: printf("Files [%s] and [%s] are identical.", szArgs[1], szArgs[2]); break;
case 1: printf("Files [%s] and [%s] are different.", szArgs[1], szArgs[2]); break;
case -1: printf("Error."); break;
}
return 0;
}
EDIT II: Personally, i have never used the C standard FILE library (it was either C++ fstream or pure win32 fileapi) so don't take my word here for granted but fread is the fastest function i could find (faster than fgets or fgetc). If you want even faster than this you should get into OS dependant functions (like ReadFile() for Windows).
chqrlie's solution using getc is absolutely the right way to do this. I wanted to address some points brought up in comments, and find it's best to do that with code. In one comment, I recommend pseudo code which could be confusing (namely, you can't write fwrite(file1...) || fwrite(file2 ...) because of the short circuit. But you can implement the idea of that with:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*
* Compare two files, 16 bytes at a time. (Purely to demonstrate memcmp.
* Clearly, this should be implemented with getc.)
*/
FILE * xfopen(const char *, const char *);
size_t xfread(void *, FILE *, const char *);
int
main(int argc, char **argv)
{
FILE *fp[2];
size_t n[2];
char buf[2][16];
unsigned count = 0;
if(argc != 3) { return EXIT_FAILURE; }
fp[0] = xfopen(argv[1], "r");
fp[1] = xfopen(argv[2], "r");
do {
n[0] = xfread(buf[0], fp[0], argv[1]);
n[1] = xfread(buf[1], fp[1], argv[2]);
if( n[0] != n[1] || (n[0] && memcmp(buf[0], buf[1], n[0]))) {
fprintf(stderr, "files differ in block %u\n", count);
return 1;
}
count += 1;
} while(n[0]);
puts("files are identical");
return 0;
}
size_t
xfread(void *b, FILE *fp, const char *name)
{
size_t n = fread(b, 1, 16, fp);
if(n == 0 && ferror(fp)) {
fprintf(stderr, "Error reading %s\n", name);
exit(EXIT_FAILURE);
}
return n;
}
FILE *
xfopen(const char *path, const char *mode)
{
FILE *fp = strcmp(path, "-") ? fopen(path, mode) : stdin;
if( fp == NULL ) {
perror(path);
exit(EXIT_FAILURE);
}
return fp;
}
New to C, I'm trying to read an input PGM file that's either P2, P5, or P6 along with an output file from the command prompt, then read the data to a buffer, and finally write it to the output file. Everything is compiling but when I view the output file only P2 looks like the original file. P5 and P6 look like a rainbow mess. I'm including my code.
#include <stdio.h>
#include <stdlib.h>
unsigned char* getPGMfile(char filename[], int *lwidth, int *lheight, int *lchannel);
int save(char filename[], unsigned char*data, int lwidth, int lheight, int lchannel);
int main(int argc, char **argv){
int lwidth, lheight, lchannel;
getPGMfile(argv[1], &lwidth, &lheight, &lchannel);
unsigned char* data=(getPGMfile(argv[1], &lwidth, &lheight, &lchannel));
printf("width, height, channel: %d %d %d\n",lwidth,lheight,lchannel);
save(argv[2], data, lwidth, lheight, lchannel);
return 0;
}
unsigned char* getPGMfile (char filename[], int *lwidth, int *lheight, int *lchannel){
FILE *in_file;
char ch;
int row, col, type;
int ch_int;
in_file = fopen(filename, "r");
if (in_file == NULL){
fprintf(stderr, "Unable to open file %s\n\n", filename);
exit(8);
}
printf("\nReading image file: %s\n", filename);
ch = getc(in_file);
if(ch != 'P'){
printf("Not valid pgm/ppm file type\n");
exit(1);
}
ch = getc(in_file);
type = ch - 48;
if((type != 2) && (type != 5) && (type != 6)){
printf("Not valid pgm/ppm file type\n");
exit(1);
}
while(getc(in_file) != '\n');
while (getc(in_file) == '#'){
while (getc(in_file) != '\n');
}
fseek(in_file, -1, SEEK_CUR);
int width, height;
fscanf(in_file,"%d%d", &width, &height);
printf("width and heigth: %d %d\n", width, height);
int intensity;
fscanf(in_file,"%d", &intensity);
printf("intensity: %d\n", intensity);
unsigned char *data;
if(type == 2){
*lchannel=5;
int k=0;
data = (unsigned char *) malloc((width*height)*sizeof(unsigned char));
for (row=height-1; row >=0; row--)
for (col=0; col<width; col++){
fscanf(in_file,"%d", &ch_int);
data[k]=ch_int;k++;
}
}
else if(type == 5){
*lchannel=6;
data=(unsigned char *) malloc(width*height*sizeof(unsigned char));
fread(data, 1, (width*height), in_file);
}
else if(type == 6){
*lchannel=6;
data=(unsigned char *) malloc(3*(width*height)*sizeof(unsigned char));
fread(data, 1, (3*(width*height)), in_file);
}
fclose(in_file);
printf("\nDone reading file\n");
*lwidth=width;
*lheight=height;
return data;
}
int save(char filename[],unsigned char *data, int lwidth, int lheight, int lchannel){
FILE *fp;
fp = fopen(filename, "wb");
const int dimx = 800, dimy = 800;
int i,j;
if(lchannel == 5){
fprintf(fp,"P5\n%u %u\n255\n", lwidth, lheight);
fwrite(data,1,(lwidth*lheight),fp);
printf("File %s saved.\n",filename);
}
else if(lchannel == 6){
fprintf(fp,"P6\n%u %u\n255\n", lwidth, lheight);
for(j=0;j<dimy;++j){
for(i=0;i<dimx;++i){
static unsigned char color[3];
color[0]=i%256;
color[1]=j%256;
color[2]=(i*j)%256;
fwrite(color,1,3,fp);
}
}
printf("File %s saved.\n",filename);
}
fclose(fp);
return(0);
free(data);
}
The fread size should be sizeof(unsigned char) rather than 1.
I'm trying to make a program that reads a file with list of names. The number of those names can vary, as well as the names lengths. I want to store them in an array of arrays of char, and read each row as a string to later open the file that corresponds to the name in question. But when I try to open the first one, I have an error opening file.
I'm totally out of ideas.
Help, please?
Here is the code relevant to this action:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int glimps(char *fname);
int write_av(char *fname, int NumbFiles);
int clr(char *fname);
int readFile(char *fname, int i);
double *dalpha, *alpha, *Ln_t, *LnLnA, Conc;
long *time, *weights, *Lmax, Nmax;
char *av_file, **in_files, *antetka;
/****************************************************************************/
int main(int argc, char *farg[])
{
int i, NumbFiles, flag;
long row;
char *a1;
FILE *fp;
av_file = farg[1];
printf("av_file = %s\n",av_file);
NumbFiles = glimps(av_file);
in_files = (char **) malloc (sizeof(char *) * NumbFiles);
for (i=0 ; i<NumbFiles ; i++)
in_files[i] = (char *) malloc (sizeof(char) * 200);
Lmax = (long *) calloc((size_t) NumbFiles, sizeof(long));
if((in_files == NULL)||(Lmax==NULL)) printf("Грешка при read алок.\n, "), exit(-1);
if (flag = readFile(av_file, -1))
printf("Error in read av_file %s\n", av_file), exit(-1);
weights = (long *) calloc((size_t) Nmax, sizeof(long));
for(i = 0; i<Nmax; i++) weights = 0;
for(i = 0; i<NumbFiles; i++)
{
//if (flag = readFile(&(*in_files[i]), i))
if (flag = readFile(in_files[i], i))
printf("Error in in_files[%d], %s\n",i, &(*in_files[i])), exit(-1);
}
if (flag = write_av(av_file, NumbFiles))
printf("Error in write_av(%s)\n,", av_file), exit(-1);
exit(0);
}
/****************************************************************************/
int glimps(char *fname)
{
FILE *fp;
char buf[140];
int cnt=0;
fp = fopen (fname, "r");
while (fgets(buf,140,fp) )
{
cnt++;
}
fclose(fp);
return (cnt);
}
/****************************************************************************/
int readFile(char *fname, int k)
{
int cnt=0;
FILE *fp;
char buf[200], dummy[13];
printf("fname is %s\n", fname); getchar();
fp = fopen (fname, "r");
if(fp==(NULL)) return(-1);
if(!strcmp(fname,av_file) )
{
while (fgets(in_files[cnt++],200,fp) );
}
else
{
printf("read TUK!\n"); getchar();
fgets(buf,200,fp);
sscanf(buf,"%s %s %s %s %s %s %s %ld %s %s %lf\n",
dummy, dummy,dummy,dummy,dummy,dummy,dummy, &Lmax[k],
dummy, dummy, &Conc);
fgets(buf,200,fp);
sscanf(buf,"%s\n", antetka);
printf("read TUK!\n"); getchar();
while (fgets(buf,200,fp))
{
sscanf(buf,"%ld %lf %lf %s %lf %lf\n",
&time[cnt], &dalpha[cnt], &alpha[cnt], dummy, &Ln_t[cnt],
&LnLnA[cnt]);
weights[cnt++]++;
}
}
fclose(fp);
return (0);
}
...
Console Output:
> ./avr alpha_cubeL.C0.010
av_file = alpha_cubeL.C0.010
fname is alpha_cubeL.C0.010
fname is alpha_cubeL100C0.010
Error in read in_files[0], alpha_cubeL100C0.010
> ls alpha_cubeL100C0.010
alpha_cubeL100C0.010
What happens is that in the readFile function, you read the main file given as argument to make (from the content) several file names in in_files[i], but fgets reads lines including the CR or CRLF (ie the end of line character(s)). Thus later in the program, readFile fails as it tries to open filename + CR [LF].
You may just add a trim function near the top of your program, like
void trim(char *s) {
int i,l = strlen(s);
for (i=l-1 ; i>=0 && (s[i]==10 || s[i]==13) ; i--) s[i] = 0;
}
that removes CR and/or LF that end a string s, and then change the readFile function to trim the file names read in each line, like
while (fgets(in_files[cnt++],200,fp) ) {
trim(in_files[cnt-1]); // cnt-1, or do the cnt++ here (and not above...)
}
Then the files can be opened...
(this is probably not the only problem in this program, but this is a good start)
Someone ask me to help them extract their pictures from a Web Shots image collection file (.WBC). I tried XnView but it did not work. How can I do this in C?
From Mike:
I hacked together some code to do the job. Here it is. It's not production quality code, so if you do not understand it then do not run it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void save_image(const char* filename, FILE* in_fp)
{
char buf[4096];
size_t read;
FILE *fp;
fp = fopen(filename, "wb");
if (!fp) {
fprintf(stderr, "cannot open file.");
exit(1);
}
do {
read = fread(buf,1,sizeof(buf),in_fp);
fwrite(buf, 1, read, fp);
} while (read);
fclose(fp);
}
int main(int argc, char* argv[])
{
char buf[4096];
unsigned int read, read_tot = 0;
FILE *fp;
int image_count = 1;
char filename[255];
unsigned int i;
char pattern[] = "JFIF";
int pi = 0;
long int curpos;
char pad[50];
char src_filename[] =
"C:\\Documents and Settings\\mikeking\\Desktop\\WBC\\"
"Custom - CATHYS WEDDING.wbc";
char des_directory[] = "C:\\Documents and Settings\\mikeking\\Desktop\\F\\";
fp = fopen(src_filename, "rb");
if (!fp) {
fprintf(stderr, "cannot open file.");
exit(1);
}
do {
read = fread(buf,1,sizeof(buf),fp);
for(i=0; i<read; i++){
if (buf[i] == pattern[pi]) {
pi++;
if (pi == sizeof(pattern)) {
strcpy(filename, des_directory);
itoa(image_count, pad, 10);
image_count++;
strcat(filename, pad);
strcat(filename, ".jpg");
curpos = ftell(fp);
fseek(fp,read_tot+i-10,SEEK_SET);
save_image(filename,fp);
fseek(fp,curpos,SEEK_SET);
}
} else {
pi = 0;
}
}
read_tot += read;
} while (read);
fclose(fp);
return 0;
}