C 使用fread()通过文件和stdin解析数据

C 使用fread()通过文件和stdin解析数据,c,algorithm,file,stdin,fread,C,Algorithm,File,Stdin,Fread,我正在尝试编写一个算法,从文件中获取输入并构建所谓的“s1记录”。(此函数的功能并不重要)根据命令行参数,程序将把inputFile设置为指定的文件,如果没有提供文件,则设置为stdin 算法的结构需要能够处理两种文件模式 其思想是获取文件*数据并将其读入16字节大小的缓冲区。每16字节的数据,将建立一个s1记录。只要有16个字节可以读取,它就可以正常工作。一旦有一行少于16字节,它就不会创建s1记录 我测试了输出,我注意到了以下几点: 当我使用“stdin”运行程序时,系统会提示用户输入。我输

我正在尝试编写一个算法,从文件中获取输入并构建所谓的“s1记录”。(此函数的功能并不重要)根据命令行参数,程序将把inputFile设置为指定的文件,如果没有提供文件,则设置为stdin

算法的结构需要能够处理两种文件模式

其思想是获取文件*数据并将其读入16字节大小的缓冲区。每16字节的数据,将建立一个s1记录。只要有16个字节可以读取,它就可以正常工作。一旦有一行少于16字节,它就不会创建s1记录

我测试了输出,我注意到了以下几点:

当我使用“stdin”运行程序时,系统会提示用户输入。我输入20个字符(一条记录中打印16个字符,另一条记录中打印4个字符),输出如下:

12345678901234567890
Buffer: 1234567890123456
S113000031323334353637383930313233343536AA
char buffer[kMaxLineSize + 1] = { '\0' };
int len;
while (len=fread(buffer, 1, kMaxLineSize, inputFile))
{
    ...
    char s1Record[kMaxSRecordSize] = { 0 };
    buildS1Record(addressField, s1Record, buffer, len);
当我使用一个文件(record.dat)运行该程序时,其中只有一行字母表中的字符,我得到以下结果:

Buffer: ABCDEFGHIJKLMNOP
Buffer: QRSTUVWXYZKLMNOP
这也是无效的,因为它也会在行尾打印“KLMNOP”

我的问题是:我如何使用相同的算法构造它来接受来自文件或stdin的输入,我的算法到底做错了什么?我已经尽力提供了我能提供的所有有用的信息,如果需要,我可以详细说明。下面是我试图编写的算法的代码

如果未指定文件,则将inputFile设置为stdin

    char buffer[kMaxLineSize + 1] = { '\0' };
    char byte = 0;

    int count = 1;

    while((fread(buffer, 1, kMaxLineSize, inputFile)))
    {
        printf("%c", byte);

        clearCRLF(buffer);
        printf("Buffer: %s\n", buffer);

        if(outputFormat == 1)
        {
            char s1Record[kMaxSRecordSize] = { 0 };
            buildS1Record(addressField, s1Record, buffer);

            fprintf(outputFile, "%s\n", s1Record);

            addressField += strlen(buffer);
            s1Count++;
        }
        else
        {
            char asmRecord[kMaxASMRecordSize] = { 0 };
            buildAssemblyRecord(asmRecord, buffer);

            fprintf(outputFile, "%s\n", asmRecord);
        }
    }

我将尝试在这个答案中结合这些评论

但首先,你所谓的s1“记录”不是记录。它是一个最多16个字符的字符串和一个终止的空字符。在我的理解中,记录是一个结构,包含可能不同类型的字段,其中一个可以是字符串

代码修复如下所示:

12345678901234567890
Buffer: 1234567890123456
S113000031323334353637383930313233343536AA
char buffer[kMaxLineSize + 1] = { '\0' };
int len;
while (len=fread(buffer, 1, kMaxLineSize, inputFile))
{
    ...
    char s1Record[kMaxSRecordSize] = { 0 };
    buildS1Record(addressField, s1Record, buffer, len);
因此,将读取的长度传递给函数。现在,它可以复制读取的字符并以
'\0'
字符终止。还请注意,
kMaxLineSize
kmaxrecordsize
之间可能存在差异:它们的大小必须相同(加上1表示
\0
),因此最好使用单个变量


我希望这个迟来的答案仍然对您有用。

建议您一次调试一个问题,一次提出一个问题。对于第二个问题,您正在询问算法实现中的错误,但您没有完全描述将输入转换为输出的算法。你说过“每16个字节的数据,就会生成一个s1记录”,但你没有告诉我们“s1记录”到底是什么。也许您认为什么是“s1记录”并不重要,但我们至少需要了解如何解释示例输出。实际上,你说输出是错误的,但我们不知道正确的输出应该是什么。s1记录在这个问题上是无关的。我想知道如何将输入解析为16字节的数组。。我只是说,这样人们就不会问我builds1record函数是什么了。很抱歉,时间真的太晚了。你能跟我说吗?它所需要做的就是基本上每16个字节分割一次数据,创建16个字节的数组,并将其传递给一个“神奇的函数”,将其转换为一个srecord。这是我需要了解的整个fread()的事情,也许你可以在更警觉的时候再来问一次。你的问题目前不连贯。现在,当问题标题询问有关stdin与文件输入的内容时,您正在询问解析数组。对于解析问题,确实不清楚问题是什么。为什么不能一次处理16个字节?
fread
告诉您读取了多少数据。继续处理16个字节,直到剩余的字节小于16。如果我这样做,剩余的4个字节左右将不会被读取?我怎样才能解决这个问题?我早就试过了