Ke. Ke. - 2 months ago 37
C Question

C Concatenate string in while loop

I'm trying to concatenate part of a struct with hex values. I run over every byte in the loop and convert to hex, then I want to concatenate all the hex into one long string.

However, I only end up with one value at the end of the loop. For some reason the string isnt concatenating properly. Any idea what Im doing wrong?

typedef struct OPTIONS_STR
{
int max;
int printName;
} OPTIONS;

void set_default_options(OPTIONS *options)
{
options->max = -1;
options->printName = 0;
}

void do_file(FILE *in, FILE *out, OPTIONS *options)
{
char ch;
int loop = 0;
char buf[81];
buf[0] = '\0';
int sz1;
int sz2;
int sz3;

int seeker = offsetof(struct myStruct, contents.datas);

//find total length of file
fseek(in, 0L, SEEK_END);
sz1 = ftell(in);

//find length from beggining to struct beginning and minus that from total length
fseek(in, seeker, SEEK_SET);
sz2 = sz1 - ftell(in);

//set seek location at beginning of struct offset
fseek(in, seeker, SEEK_SET);

sz3 = sz2 + 1;
char buffer[sz3];
char msg[sz3];

buffer[0] = '\0';

while (loop < sz2)
{
if (loop == sz2)
{
break;
}

fread(&ch, 1, 1, in);
sprintf(msg, "%02X", (ch & 0x00FF));
strcpy(buffer, msg);

++loop;
}
printf("%s\n", buffer);
}

int main(int argc, const char * argv[]) {

OPTIONS options;
set_default_options(&options);

const char *current = "/myfile.txt";
FILE *f = fopen(current, "rb");
do_file(f, stdout, &options);
fclose(f);

};

Answer

Use strcat instead of strcpy. That should fix your problem.

For efficiency look into using a write pointer like char *p = buffer and advance the write position with something like p += sprintf(p, "%02X", (ch & 0x00FF))

Also your if(loop == sz2) break check is a useless duplicate of the while(loop < sz2) check. The while loop won't execute if loop is equal or bigger than sz2.

Also wondering why you use fread when you only want one character. fgetc or getc seems to be a better choice.

Also, no matter if you use fread or getc you need to check for the end of file. What if the file does not have sz2 bytes in it? Because all modern systems are multiprocess and multiuser, so someone might cut the file short after the call to ftell. You should never assume things because even if you just checked it, it can change. Making that assumption is what causes TOCTTOU (Time of Check To Time Of Use) bugs.