C :如何将C-Library File IO转换为C 流IO

C++: How to convert C-library file IO to C++ stream IO?

本文关键字:IO 转换 File C-Library      更新时间:2023-10-16

我具有如下所述的功能,在此函数中,将文件名发送为参数,然后将其打开,然后读取和使用其中的内容。我要实现的是相同的功能,但是通过将字符串(文件内容)直接传递给该功能。因此,我想确切地知道我应该如何处理并转换诸如fgetsfeof

之类的方法
unsigned CalcChecksum(char *filename, unsigned &found_checksum)
{
    unsigned s, c, fcs;
    char *ch;
    char input[256];
    FILE *fp;
    s = 0;
    fp = fopen(filename, "rb");
    if (!fp)
    {
        found_checksum = 1;
        return 0;
    }
    ch = fgets(input, 255, fp);
    if ((feof(fp)) || (strncmp(input, "checksum", 8) == 0))
    {
        fclose(fp);
        return s;
    }
    while (1)
    {
        while (*ch != 'n')
        {
            c = (unsigned)*ch++;
            s = CRCtab[(s^c) & 0xFF] ^ s >> 8;
        }
        ch = fgets(input, 255, fp);
        if ((feof(fp)) || (strncmp(input, "checksum", 8) == 0))
            break;
    }
    if (strncmp(input, "checksum", 8) == 0)
    {
        fcs = 0;
        sscanf(input, "checksum 0x%x", &fcs);
        if (fcs == 0)
            sscanf(input, "checksum 0X%X", &fcs);
        found_checksum = fcs;
    }
    else
        found_checksum = 0;
    fclose(fp);
    return s;
}

您可以用char *或std ::字符串作为输入。

unsigned CalcChecksum(char *fileContent, unsigned &found_checksum){
    int contentLength = strlen(filecContent);
    while(contentLength > 0){
        ...
        strncpy(input, fileContent, 255);
        fileContent+=255;
        contentLength-=255;
        ...
    }
}

或std :: string

unsigned CalcChecksum(string fileContent, unsigned &found_checksum){
    int contentLength =filecContent.length();
    int pos = 0;
    while(contentLength > 0){
        ...
        input = fileContent.substr(pos, 255);
        pos+=255;
        contentLength-=255;
        ...
    }
}

有点偏离主题,但是实现校验和函数时的一个频繁错误是从(签名) charunsigned的转换不正确的,就像代码中的一个:

中的一个错误。
c = (unsigned)*ch++;

示例:

#include <cstdio>
unsigned checksum1(char const* data, size_t data_len) {
    unsigned s = 0;
    for(char const* end = data + data_len; data != end; ++data)
        s += *data; // <--- incorrect conversion, same as s += (unsigned)*data.
    return s;
}
unsigned checksum2(char const* data, size_t data_len) {
    unsigned s = 0;
    for(char const* end = data + data_len; data != end; ++data)
        s += static_cast<unsigned char>(*data); // <--- correct conversion
    return s;
}
int main() {
    char const s[] = "© example.com";
    std::printf("%u %un", checksum1(s, sizeof s - 1), checksum2(s, sizeof s - 1));
}

输出:

996 1508

这是因为(隐式)整数转换首先调整宽度,然后更改签名。例如,char('©')变为int(-62),然后变为unsigned(4294967234)。签名必须首先更改:char('©')变为unsigned char(168),然后是unsigned(168)

colcchecksum方法现在接受弦乐作为param。

unsigned CalcChecksumFromString(std::stringstream& stream, unsigned &found_checksum)
{
    unsigned s, c, fcs;
    char *ch;
    s = 0;
    if (!stream.rdbuf()->in_avail() == 0)
    {
        found_checksum = 1;
        return 0;
    }
    std::string input;
    std::getline(stream, input);
    if ((stream.eof()) || (strncmp(input.c_str(), "checksum", 8) == 0))
    {
        return s;
    }
    do
        {
        for (char& c : input) 
        {
            c = static_cast<unsigned char>(c);
            s = CRCtab[(s^c) & 0xFF] ^ s >> 8;
        }
        if ((stream.eof()) || (strncmp(input.c_str(), "checksum", 8) == 0))
            break;
    } while (std::getline(stream, input));
    if (strncmp(input.c_str(), "checksum", 8) == 0)
    {
        fcs = 0;
        sscanf(input.c_str(), "checksum 0x%x", &fcs);
        if (fcs == 0)
            sscanf(input.c_str(), "checksum 0X%X", &fcs);
        found_checksum = fcs;
    }
    else
        found_checksum = 0;
    return s;
}