我正在尝试使用十六进制值连接结构的一部分。我遍历循环中的每个字节并转换为十六进制,然后我想将所有十六进制连接成一个长字符串。
但是,我只在循环结束时得到一个值。由于某种原因,字符串没有正确连接。知道我做错了吗?
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);
};
答案 0 :(得分:3)
使用strcat
代替strcpy
。这应该可以解决你的问题。
为了提高效率,请考虑使用像char *p = buffer
这样的写指针,并使用类似p += sprintf(p, "%02X", (ch & 0x00FF))
此外,您的if(loop == sz2) break
支票是while(loop < sz2)
支票的无用副本。如果loop
等于或大于sz2
,则不会执行while循环。
还想知道为什么在只需要一个角色时使用fread
。 fgetc
或getc
似乎是更好的选择。
此外,无论您使用fread
还是getc
,都需要检查文件的结尾。如果文件不中有sz2
个字节,该怎么办?因为所有现代系统都是多进程和多用户,所以有人可能会在调用ftell
之后缩短文件。你永远不应该假设,因为即使你只是检查它,它也可以改变。做出这个假设是导致TOCTTOU(使用时间检查时间)错误的原因。
答案 1 :(得分:-1)
在do_file()
中,您将在while循环中复制单个字节的十六进制值。因此,您应该在while循环的每次迭代中转到字符数组buffer
的下一个字节,即buffer++
或strcpy(buffer[loop], msg);