如何在运行时

时间:2015-07-08 20:17:14

标签: c

我在C工作,我正在修改现有代码。

我有一个char数组,它存储在一个文件中,如下所示:

"\x01\x02\x03"
"\x04\x05\x06"
"\x07\x08\x09"

在原始源代码中,此char数组包含如下:

const static char chs[] =
#include "file.h"
;

我修改此代码以在运行时将文件加载到char数组中(以获得与上述方法完全相同的结果),而不是预处理器包含它。我的第一种方法是简单地将文件读入char缓冲区,如下所示:

FILE *fp;
const char *filename = "file.h";
fp = fopen (filename, "rb");
assert(fp != NULL);

fseek(fp, 0L, SEEK_END);
long int size = ftell(fp);
rewind(fp);

// read entire file into the buffer
char *buffer = (char*)malloc(sizeof(char) * size);
size_t nrOfBytesRead = fread(buffer, 1, size, fp);

然而,我很快发现这不正确。该文件已包含char数组的确切代码表示,我不能简单地将其读入char缓冲区并获得与include方法相同的结果。

在运行期间将存储在文件中的char数组放入char数组的最佳方法是什么?

2 个答案:

答案 0 :(得分:5)

正如您所见,当您使用fread读取文件时,它会逐字节地读取它。它没有得到编译器对源文件执行的任何语法处理。它并不知道字符串存在于引号内。它不会将\x01之类的转义序列映射为单个字节。

您有几种不同的可能性来解决这个问题:

  1. 教你的程序在读取文件时如何进行处理。这将是相当多的工作。
  2. 将您想要的字节放入文件中。
  3. 为您的文件选择不同的编码。
  4. 再说一下#2:如果你不想改变你的文件阅读代码,你可以做的是创建一个(在这种情况下)9字节的文件,只包含9个字节你要。由于你的九个字节不是文本,它最终会成为一个"二进制文件"文件,你不能用普通的文本编辑器直接编辑,等等。(事实上,根据你可以使用的工具,创建这个特殊的9字节文件可能具有挑战性。 )

    因此,如果你不能使用#1或#2,你可能想要使用#3:选择一种全新的方式来编码文件中的数据,比#1更容易解析,但更容易准备比#2。我的第一个想法是让文件是十六进制的。也就是说,该文件将包含

    010203040506070809
    

    010203
    040506
    070809
    

    您的文件读取代码(而不是对fread的单次调用)将一次读取两个字符并将它们组合成阵列的字节。 (我为你画了这个,但是我正在等待的汇编已经完成了,我应该回到我的工作岗位。)

答案 1 :(得分:1)

这应该从文件中读取十六进制值并将其保存到buffer fgets()从文件中读取每一行 sscanf()从行中读取每个十六进制值 sscanf的格式字符串"\\x%x%n"扫描反斜杠,x,十六进制值并存储扫描处理的字符数。处理的字符数用于前进。如果某些行具有不同数量的十六进制值,则需要这样做。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    char line[100] = {'\0'};
    unsigned char *buffer = NULL;
    unsigned char *temp = NULL;
    unsigned int hex = 0;
    int size = 0;
    int offset = 0;
    int used = 0;
    int bufferused = 0;
    int increment = 100;
    int each = 0;
    FILE *pf = NULL;

    if ( ( pf = fopen ( "file.h", "r")) != NULL) {
        while ( fgets ( line, sizeof ( line), pf)) {//get each line of the file
            offset = 1;//to skip leading quote
            //sscanf each hex value in the line
            while ( ( sscanf ( line + offset, "\\x%x%n", &hex, &used)) == 1) {
                offset += used;// to advance through the line
                if ( bufferused >= size) {
                    temp = realloc ( buffer, size + increment);
                    if ( temp == NULL) {
                        //one way to handle the failure
                        printf ( "realloc failed\n");
                        free ( buffer);
                        exit (1);
                    }
                    buffer = temp;
                    size += increment;
                }
                buffer[bufferused] = hex;
                bufferused++;
            }
        }
        fclose ( pf);
    }
    for ( each = 0; each < bufferused; each++) {
        printf ( "%x\n", buffer[each]);
    }
    free ( buffer);

    return 0;
}