2017-02-20 92 views
0

我有這樣一個函數,在這個函數中,文件名是作爲參數發送的,然後打開它並讀取和使用它的內容。我想達到的是相同的功能,但通過直接將字符串(文件內容)傳遞給該函數。所以,我想知道我究竟應該如何處理這和轉換像fgets方法,feofC++:如何將C庫文件IO轉換爲C++流IO?

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; 
} 
+0

這看起來像一個簡單的C代碼。無論如何,你應該學習一些關於[C字符串](https://www.programiz.com/c-programming/c-strings)。 – Melebius

+0

「像下面提到的那樣」?這是功能還是不是?而究竟*是什麼問題?正如所發佈的,這似乎更多的是一個目標,而不是關於實際問題的問題。你問如何將C庫文件IO轉換爲C++流IO?這是一個多步驟的過程,第一步是理解C++ IO流庫以及他們可以/不可以做什麼。 – WhozCraig

+0

'如何將C庫文件IO轉換爲C++流IO?'是的,這似乎是提出問題的最佳方式。我不希望整個函數被轉換,但得到一個想法如何將Clib IO轉換爲C++流IO。 –

回答

0

您可以使用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; 
     ... 
    } 
} 
0

有點偏離主題,但實現的校驗功能,當一個頻繁的錯誤是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 %u\n", checksum1(s, sizeof s - 1), checksum2(s, sizeof s - 1)); 
} 

輸出:

996 1508 

這是因爲(隱含的)整數轉換第一調整寬度,然後改變符號類型。例如,char('©')變成int(-62)然後unsigned(4294967234)。必須首先更改簽名:char('©')變爲unsigned char(168),然後unsigned(168)

0

CalcChecksum方法現在接受stringstream作爲參數。

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; 
}