在C语言中从文件读取到int缓冲区

在C语言中从文件读取到int缓冲区,c,C,我有一个包含数千行的txt文件。每条线的长度各不相同。txt文件主要包含以字节为单位的十六进制数据。例如: 01 04 03=4个字节 第二行可能包含8个字节,第三行可能包含40个字节,依此类推。有成千上万条这样的线路 现在我想把这些字节读入int缓冲区。我正在读取char缓冲区,它在内存中保存为0001 0001 0004 0003,我不想要它,它被认为是8字节。在内存中,它作为字符缓冲区保存为3031 3031 3034 3030(ASCII)。我正在将其转换为0001 0001 0004

我有一个包含数千行的txt文件。每条线的长度各不相同。txt文件主要包含以字节为单位的十六进制数据。例如:

01 04 03=4个字节

第二行可能包含8个字节,第三行可能包含40个字节,依此类推。有成千上万条这样的线路

现在我想把这些字节读入int缓冲区。我正在读取char缓冲区,它在内存中保存为0001 0001 0004 0003,我不想要它,它被认为是8字节。在内存中,它作为字符缓冲区保存为3031 3031 3034 3030(ASCII)。我正在将其转换为0001 0001 0004 0003

下面是我的一段代码

FILE *file;

char buffer[100] = { '\0' };
char line[100] = { '0' }; 

if(file!=NULL)
      {
        while(fgets(line, sizeof(line), file)!=NULL)
        {

          for(i = 0; (line[i] != '\r') ; i++)
          {
              buffer[i] = line[i];
          }
        }
       }

我想逐行读取,而不是一次读取整个文件。在记忆中我只想看到01 04 03。我想使用int缓冲区会有所帮助。一旦它将文件读入缓冲行,它就被存储为char。有什么建议吗?

我会读一行,然后用
strtol
转换输入中的单个数字
strtol
为您提供一个指向转换失败的字符的指针,您可以使用该指针作为查找/转换下一个数字的起点。

我将读取一行,然后使用
strtol
转换输入中的各个数字
strtol
为您提供一个指向转换失败的字符的指针,您可以将该指针用作查找/转换下一个数字的起点。

您可以转换小的十六进制数:

#include <ctype.h>
uint8_t digits2hex(char *digits) {
  uint8_t r = 0;
  while (isxdigit(*digits)) {
    r = r * 16 + (*digit - '0');
    digit++;
    /* check size? */
  }
  return r;
}

您可以转换小的十六进制数:

#include <ctype.h>
uint8_t digits2hex(char *digits) {
  uint8_t r = 0;
  while (isxdigit(*digits)) {
    r = r * 16 + (*digit - '0');
    digit++;
    /* check size? */
  }
  return r;
}

您似乎混淆了字节的文本表示形式和字节的值(或者期望编译器做得更多)

当您的程序读入“01”时,它将读入两个字节,其值对应于字符“0”和“1”的ASCII码。C没有对它们做任何特殊的处理,所以您需要将这个序列转换成一个单字节的值。请注意,C字符是一个字节,因此是保存此结果的正确大小。这是一种巧合,对于Unicode和其他宽字符编码,在任何情况下都是不正确的

有几种方法可以进行这种转换。您可以自己对字节进行如下运算:

unsigned char charToHex(char c) {
    if (isdigit(c)) return c - '0';
    return 9 + toupper(c) - 'A';
}

...

first = getc(fh);
second = getc(fh);
buffer[*end] = charToHex(first) << 4 | charToHex(second);
与此相关,使用getc()一次读取文件中的一个字符,忽略任何非十六进制数字的内容,可能会更幸运。这样,如果输入行比传递给fgets()的缓冲区长,就不会出现缓冲区溢出。它还可以更容易地容忍输入文件中的垃圾

这里有一个完整的例子。它使用isxdigit()检测十六进制字符,并忽略任何其他内容,包括单个十六进制数字:

// Given a single hex digit, return its numeric value
unsigned char charToHex(char c) {
    if (isdigit(c)) return c - '0';
    return 9 + toupper(c) - 'A';
}

// Read in file 'fh' and for each pair of hex digits found, append
// the corresponding value to 'buffer'. '*end' is set to the index
// of the last byte written to 'buffer', which is assumed to have enough
// space.
void readBuffer(FILE *fh, unsigned char buffer[], size_t *end) {
    for (;;) {

        // Advance to the next hex digit in the stream.
        int first;
        do {
            first = getc(fh);
            if (first == EOF) return;
        } while (!isxdigit(first));

        int second;
        second = getc(fh);

        // Ignore any single hex digits
        if (!isxdigit(second)) continue;

        // Compute the hex value and append it to the array.
        buffer[*end] = charToHex(first) << 4 | charToHex(second);
        (*end)++;

    }
}
//给定一个十六进制数字,返回其数值
无符号字符charToHex(字符c){
if(isdigit(c))返回c-'0';
返回9+toupper(c)-‘A’;
}
//读入文件“fh”,并为找到的每对十六进制数字追加
//“缓冲区”的对应值*“结束”设置为索引
//写入“缓冲区”的最后一个字节的
//空间。
void readBuffer(文件*fh,无符号字符缓冲区[],大小*end){
对于(;;){
//前进到流中的下一个十六进制数字。
int优先;
做{
第一个=getc(fh);
if(first==EOF)返回;
}而(!isxdigit(first));
int秒;
秒=getc(fh);
//忽略任何单个十六进制数字
如果(!isxdigit(秒))继续;
//计算十六进制值并将其附加到数组中。

buffer[*end]=charToHex(first)您似乎混淆了字节的文本表示形式与字节的值(或者,期望编译器做得更多)

当您的程序读入“01”时,它将读入两个字节,其值对应于字符“0”和“1”的ASCII码.C对它们没有任何特殊作用,因此您需要将此序列转换为一个字节值。请注意,C字符是一个字节,因此是保存此结果的正确大小。这是一种符合的情况,对于Unicode和其他宽字符编码,在任何情况下都是不符合的

有几种方法可以进行此转换。您可以自己对字节进行如下运算:

unsigned char charToHex(char c) {
    if (isdigit(c)) return c - '0';
    return 9 + toupper(c) - 'A';
}

...

first = getc(fh);
second = getc(fh);
buffer[*end] = charToHex(first) << 4 | charToHex(second);
与此相关的是,使用getc()一次读取文件中的一个字符,忽略任何非十六进制数字的内容,可能会有更好的运气。这样,如果输入行比传递给fgets()的缓冲区长,就不会出现缓冲区溢出。这也使得更容易容忍输入文件中的垃圾

下面是一个完整的示例。它使用isxdigit()检测十六进制字符,并忽略任何其他内容,包括单个十六进制数字:

// Given a single hex digit, return its numeric value
unsigned char charToHex(char c) {
    if (isdigit(c)) return c - '0';
    return 9 + toupper(c) - 'A';
}

// Read in file 'fh' and for each pair of hex digits found, append
// the corresponding value to 'buffer'. '*end' is set to the index
// of the last byte written to 'buffer', which is assumed to have enough
// space.
void readBuffer(FILE *fh, unsigned char buffer[], size_t *end) {
    for (;;) {

        // Advance to the next hex digit in the stream.
        int first;
        do {
            first = getc(fh);
            if (first == EOF) return;
        } while (!isxdigit(first));

        int second;
        second = getc(fh);

        // Ignore any single hex digits
        if (!isxdigit(second)) continue;

        // Compute the hex value and append it to the array.
        buffer[*end] = charToHex(first) << 4 | charToHex(second);
        (*end)++;

    }
}
//给定一个十六进制数字,返回其数值
无符号字符charToHex(字符c){
if(isdigit(c))返回c-'0';
返回9+toupper(c)-‘A’;
}
//读入文件“fh”,并为找到的每对十六进制数字追加
//与“缓冲区”对应的值。“*end”设置为索引
//写入“缓冲区”的最后一个字节的
//空间。
void readBuffer(文件*fh,无符号字符缓冲区[],大小*end){
对于(;;){
//前进到流中的下一个十六进制数字。
int优先;
做{
第一个=getc(fh);
if(first==EOF)返回;
}而(!isxdigit(first));
int秒;
秒=getc(fh);
//忽略任何单个十六进制数字
如果(!isxdigit(秒))继续;
//计算十六进制值并将其附加到数组中。

buffer[*end]=charToHex(first)使用“\r”结束循环时存在两个问题。首先,“\r”(0x0D)通常只出现在Windows上保存的文件中,该文件以“\r\n”结尾。Linux和现代苹果软件使用“\n”(0x0A)只有。如果有任何问题,请忽略“\r”并在“\n”处断开。其次,如果线条长度超过99