2

如何从文件中读取 64 位无符号整数?我将它存储为实际的二进制数据,而不是字符串表示形式。

4

4 回答 4

3

它是如何编码的?二进制数的字节序通常不同。如果你想假设它与当前主机的字节序相同,你可以fread直接使用。否则,您需要在阅读后对其进行字节交换。

对于奖励积分,假设您可以控制它的序列化方式,您可以使用一些标志或字节顺序标记来指示字节顺序。

于 2012-08-27T00:05:21.710 回答
3

像这样的东西:

FILE * fp = fopen("file.bin", "rb");

uint64_t value;
if (fread(&value, sizeof value, fp) != sizeof value) { /* error */ }

// ...

fclose(fp);

如果是您编写数据,这应该是开箱即用的。如果数据来自其他地方,请检查二进制格式的文档以说明序列化格式和您的平台之间的表示差异(例如,可能需要字节交换)。


另一种在教学上更有用但效率较低的方法是将数据读入缓冲区并应用您自己的处理。这更灵活(例如,您可以处理像 3-2-1-4-7-8-6-5 这样的疯狂字节序),但可能要慢得多:

unsigned char buf[sizeof uint64_t];
if (fread(buf, sizeof buf, fp) != sizeof buf) { /* error */ }
uint64_t leval = buf[0] + (buf[1] << 8) + /* ... */;
uint64_t beval = buf[7] + (buf[6] << 8) + /* ... */;
uint64_t ceval = (buf[0] << 16) + (buf[1] << 8) + buf[2] + (buf[3] << 24) + /* ... */;
于 2012-08-27T00:10:40.873 回答
0
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

//function to dump hex from file.
void hexdump(const char *const filename)
{
    FILE         *file;
    unsigned char byte;


    file = fopen(filename, "rb");
    if (file == NULL)
        return;
    fprintf(stdout, "hexdump of `%s': ", filename);
    while (fread(&byte, 1, 1, file) == 1)
        fprintf(stdout, "0x%02x ", byte);
    fprintf(stdout, "\n");
}

int main(void) {
    //x64
    //write text, write binary,
    //read text, read binary

    FILE *fout, *filein;
    char *filename_txt = "myfile.txt";  //text filename
    char *filename_bin = "myfile.bin";  //bin filename

    //unsigned long long my64 = 0x1234567887654321;
    //two x64 numbers
    uint64_t my64 = 258;                        //258 (dec) = 102(hex) =  0000 0000 0000 0102 -> 0201 0000 0000 0000 -> 2010000000000000 -> to file
    uint64_t my642 = 1234567891011121314;       //1234567891011121314(dec) = 112210F4B2D230A2 (hex) = 1122 10F4 B2D2 30A2 -> A230 D2B2 F410 2211 -> A230D2B2F4102211 -> to file

    // write as text
    fout = fopen(filename_txt, "wt");
    fprintf(fout, "%" PRIu64 "\n", my64);
    fprintf(fout, "%" PRIu64 "\n", my642);
    fclose(fout);    

    // write as bytes
    fout = fopen(filename_bin, "wb");
    fwrite(&my64, sizeof(my64), 1, fout);
    fwrite(&my642, sizeof(my64), 1, fout);
    fclose(fout);    

    // read as text
    filein = fopen(filename_txt, "rt");
    if(filein==NULL){printf("Cann't open file \"myfile.txt\" for reading...\n");}
    else{
        printf("Try to reading file as text\n");
        char buf[1000];
        while (fgets(buf,1000,filein)!=NULL)
            printf("%s",buf);
        fclose(filein);
    }


    // read as bytes
        /* check that the content of the file is not printable, i.e. not text */
        hexdump(filename_bin);

    filein = fopen(filename_bin, "rb");
    if (filein == NULL){
        printf("Cann't open file \"myfile.bin\" for reading...\n");
        return -1;
    }
    else{
        uint64_t value;
        printf("Try to reading file as bytes\n");
        value = 0;

        while(fread(&value, sizeof(value), 1, filein) == 1){
            fprintf(stdout, "The value read was %" PRIu64 "\n", value);
        }

        fclose(filein);
    }

    system("pause");
    return 0;
}
于 2018-09-18T07:29:43.823 回答
0

有人谈到了可移植性问题,所以我在这里发布了带有 (unsigned long long) 的修改版本。请参阅代码中的注释。

#include <stdio.h>
//#include <stdlib.h>   //this need to working system("pause"); only
                        //system("pause"); need only to don't close window
                        //if program running by double click on exe in windows.
//#include <inttypes.h> //this need to working with uint64_t    and no need to working with (unsigned long long)

//function to dump hex from file.
void hexdump(const char *const filename)
{
    FILE         *file;
    unsigned char byte;


    file = fopen(filename, "rb");
    if (file == NULL)
        return;
    fprintf(stdout, "hexdump of `%s': ", filename);
    while (fread(&byte, 1, 1, file) == 1)
        fprintf(stdout, "0x%02x ", byte);
    fprintf(stdout, "\n");
}

int main(void) {
    //x64
    //write text, write binary,
    //read text, read binary

    FILE *fout, *filein;
    char *filename_txt = "myfile.txt";  //text filename
    char *filename_bin = "myfile.bin";  //bin filename

    //two x64 numbers

    //uint64_t
    //uint64_t my64 = 258;                      //258 (dec) = 102(hex) =  0000 0000 0000 0102 -> 0201 0000 0000 0000 -> 2010000000000000 -> to file
    //uint64_t my642 = 1234567891011121314;    //1234567891011121314(dec) = 112210F4B2D230A2 (hex) = 1122 10F4 B2D2 30A2 -> A230 D2B2 F410 2211 -> A230D2B2F4102211 -> to file

    //unsigned long long x64
    unsigned long long my64 = 1234567887654321; //as 64 bit integer
    unsigned long long my642 = 0x462D53C650DB1; //the same number, as hex

    // write as text
    fout = fopen(filename_txt, "wt");

//uint64_t
//  fprintf(fout, "%" PRIu64 "\n", my64);
//  fprintf(fout, "%" PRIu64 "\n", my642);

//unsigned long long
    fprintf(fout, "%llu%llu\n", my64);
    fprintf(fout, "%llu%llu\n", my642);

    fclose(fout);   

    // write as bytes
    fout = fopen(filename_bin, "wb");
    fwrite(&my64, sizeof(my64), 1, fout);   //write first number
    fwrite(&my642, sizeof(my64), 1, fout);  //write second number
    fclose(fout);   

    // read as text
    filein = fopen(filename_txt, "rt");
    if(filein==NULL){printf("Cann't open file \"myfile.txt\" for reading...\n");}
    else{
        printf("Try to reading file as text\n");
        char buf[1000];
        while (fgets(buf,1000,filein)!=NULL)
            printf("%s",buf); //just print buf as string.
        fclose(filein);
    }


    // read as bytes
        /* check that the content of the file is not printable, i.e. not text */
        hexdump(filename_bin);

    filein = fopen(filename_bin, "rb");
    if (filein == NULL){
        printf("Cann't open file \"myfile.bin\" for reading...\n");
        return -1;
    }
    else{
        //uint64_t value;
        unsigned long long int value;
        printf("Try to reading file as bytes\n");
        value = 0;

        while(fread(&value, sizeof(value), 1, filein) == 1){
//          fprintf(stdout, "The value read was %" PRIu64 "\n", value);     //uint64_t
            fprintf(stdout, "The value read was %llu%llu\n", value);        //unsigned long long
        }

        fclose(filein);
    }

    //system("pause");
    return 0;
}

如果变量的类型为无符号字符,则可以将 1 个字节整数写入二进制并从二进制中读取。

于 2018-09-18T23:46:27.597 回答