使用fscanf()读取unsigned long long

时间:2012-08-27 00:01:24

标签: c file scanf

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

4 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分: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) + /* ... */;

答案 2 :(得分: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;
}

答案 3 :(得分:0)

有人谈到了可移植性问题,因此我在此处发布了修改后的版本,其中包含 (无符号长久)。参见代码中的注释。

#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个字节整数可以写为二进制,也可以从二进制中读取 如果变量的类型为-无符号字符。