gpt4 book ai didi

c - 使用 fread 时如何忽略/处理换行符 (0A)?

转载 作者:行者123 更新时间:2023-11-30 14:31:34 29 4
gpt4 key购买 nike

我目前正在尝试编写一个函数,将输入数据的每个字节转换为定义常量字节(汇编指令)。

void toASM(FILE *inputFile, FILE *outputFile) {
char buffer[16 + sizeof(char)] = "";
int bytes = 0;
while ((bytes = fread(buffer, sizeof(char), 16, inputFile))) { // start reading block of data from stream
for (int i = 0; i < bytes; i++) {
if (i == bytes - 1) {
if((buffer[i] != '\r') && (buffer[i] != '\n')) {
fprintf(outputFile, "$%.2X\n", buffer[i]);
} else {
printf("\n");
}
} else {
fprintf(outputFile, "$%.2X,", buffer[i]);
}
}
}
}

这个函数工作正常,我似乎无法解决的唯一问题是,最后它会产生一个“$0A”,我认为它是换行符或换行符。

我最好的猜测是我的 while 循环正在读取输入的最后一行,结果返回“$0A”

ABCDEFGHIJKLMNOPQRSTUVWXYZ 的电流输出

$41,$42,$43,$44,$45,$46,$47,$48,$49,$4A,$4B,$4C,$4D,$4E,$4F,$50
$51,$52,$53,$54,$55,$56,$57,$58,$59,$5A,

不检查换行或换行的输出

$41, $42, $43, $44, $45, $46, $47, $48, $49, $4A, $4B, $4C, $4D, $4E, $4F, $50
$51, $52, $53, $54, $55, $56, $57, $58, $59, $5A, $0A

我想要的输出

$41, $42, $43, $44, $45, $46, $47, $48, $49, $4A, $4B, $4C, $4D, $4E, $4F, $50
$51, $52, $53, $54, $55, $56, $57, $58, $59, $5A

当前的问题是额外的“,”,但更大的问题是,如果输入文件包含多行数据,ASM 输出将包含随机新行。这是由于我的 else 语句执行了 printf("\n");

所以我想知道是否有更好的替代方案来做到这一点?

最佳答案

这段代码展示了我通常使用的技术。它将逗号空格视为除第一个项目之外的项目的前缀;第一个有一个空字符串作为前缀(或者前导缩进,如果您希望数据缩进,或者标签,或者......)。

#include <stdio.h>

static inline int iseol(unsigned char c) { return (c == '\n' || c == '\r'); }

static
void toASM(FILE *inputFile, FILE *outputFile)
{
unsigned char buffer[16];
int bytes;
while ((bytes = fread(buffer, sizeof(buffer[0]), sizeof(buffer), inputFile)) > 0)
{
const char *pad = "";
for (int i = 0; i < bytes; i++)
{
if (!iseol(buffer[i]))
{
fprintf(outputFile, "%s$%.2X", pad, buffer[i]);
pad = ", ";
}
else if (pad[0] != '\0')
{
printf("\n");
pad = "";
}
}
if (pad[0] != '\0')
putchar('\n');
}
}

int main(void)
{
toASM(stdin, stdout);
return 0;
}

iseol() 函数可能有点过分了;使用原来的测试是可以的。正式来说,它是 reserved identifier — 使用 is_eol() 是安全的,isEOL() 也是如此。

程序源码为asm67.c,编译为程序asm67。我使用输入文件 input 进行测试,内容为:

ABCDEFGHIJKLMNOPQRSTUVWXYZ

最简单的测试用例产生:

$ asm67 < input
$41, $42, $43, $44, $45, $46, $47, $48, $49, $4A, $4B, $4C, $4D, $4E, $4F, $50
$51, $52, $53, $54, $55, $56, $57, $58, $59, $5A
$

这看起来像你所要求的。下面显示了 4 行输入的输出,每行包含字母表和换行符。如果这不是您想要的,您应该在问题中指定此类情况的所需输出。获得所需输出所需的测试可能不是很复杂。

$ cat input input input input | asm67
$41, $42, $43, $44, $45, $46, $47, $48, $49, $4A, $4B, $4C, $4D, $4E, $4F, $50
$51, $52, $53, $54, $55, $56, $57, $58, $59, $5A
$41, $42, $43, $44, $45
$46, $47, $48, $49, $4A, $4B, $4C, $4D, $4E, $4F, $50, $51, $52, $53, $54, $55
$56, $57, $58, $59, $5A
$41, $42, $43, $44, $45, $46, $47, $48, $49, $4A
$4B, $4C, $4D, $4E, $4F, $50, $51, $52, $53, $54, $55, $56, $57, $58, $59, $5A
$41, $42, $43, $44, $45, $46, $47, $48, $49, $4A, $4B, $4C, $4D, $4E, $4F
$50, $51, $52, $53, $54, $55, $56, $57, $58, $59, $5A
$

请注意,对于 4 行输入,其中一个 16 字节 block 以换行符开头;使用 if (pad[0] != '\0') 的代码逻辑可防止在输出中留下空行。

提供一个接受输入文件流和输出文件流的函数是一个好主意。测试程序显示了使用标准输入和标准输出进行测试是多么简单。

关于c - 使用 fread 时如何忽略/处理换行符 (0A)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60236003/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com