【问题标题】:Why the incorrect data are read from fscanf?为什么从 fscanf 读取不正确的数据?
【发布时间】:2016-07-22 23:17:53
【问题描述】:

我试图通过 fscanf 从文件中读取数据,然后打印数据。 但是,有些数据是不正确的。有四列。只有第三列数据有问题。另一列没问题。

小数从文件中读取正确,但大数据饱和到26843519,看来是数据类型限制了。但是26843519这个数字并不是特定数据类型的限制数。

我尝试更改许多数据类型。我仍然无法解决这个问题。

你能帮忙吗?

编译和运行系统: I7-4790,ubuntu 14.04.1 x86_64,gcc(g++) 4.8.4

来源:

while(!feof(trace_file))
{
double time;
unsigned long location;
unsigned int req_size, temp; 
char op_type[10];

//fscanf(trace_file, "%s\t%lf\t%d\n", op_type, &time, &location);
fscanf(trace_file, "%lf %s %lu %d %d \n", &time, op_type, &location, &req_size, &temp);

// for debug
printf("[Application] OP : %s     Location : %lu     Time : %lf    Size : %d\n", op_type, location, time, req_size);

输入数据文件:

(第三列有问题。)

128166477394345573     Read     383496192     32768     113736
128166483087163644     Read     2822144     65536     71730 
128166620794097839     Read     3221266432     4096     121008
128166624207799335     Read     3354624     49152     147664
128166624207887065     Read     2961408     57344     59933
128166624210238731     Read     368979968     65536     52003
128166624211812801     Read     395730944     65536     40423
128166624211962708     Read     442093568     65536     46765
128166624211968354     Read     437964800     65536     41118
128166624212755738     Read     396734464     49152     34979
128166624212868365     Read     386232320     20480     78602
128166624212905977     Read     398438400     45056     40989
128166624213527427     Read     378523648     65536     44536
128166624213988219     Read     404738048     65536     52490
128166624213996455     Read     404475904     65536     44254
128166624232905615     Read     381739008     65536     41223
128166624242878893     Read     439144448     57344     67882
128166624242935246     Read     3608576     57344     11528
128166624243149609     Read     386646016     65536     109663
128166624243365012     Read     398176256     65536     50510
128166624274398038     Read     397676544     32768     111035
128166624295029088     Read     6320128     65536     104853

输出结果(通过 printf):

(第三个数据将输出到“位置”。)

[Application] OP : Read     Location : 26843519     Time : 128166477394345568.000000    Size : 32768
[Application] OP : Read     Location : 2822144     Time : 128166483087163648.000000    Size : 65536
[Application] OP : Read     Location : 26843519     Time : 128166620794097840.000000    Size : 4096
[Application] OP : Read     Location : 3354624     Time : 128166624207799328.000000    Size : 49152
[Application] OP : Read     Location : 2961408     Time : 128166624207887072.000000    Size : 57344
[Application] OP : Read     Location : 26843519     Time : 128166624210238736.000000    Size : 65536
[Application] OP : Read     Location : 26843519     Time : 128166624211812800.000000    Size : 65536
[Application] OP : Read     Location : 26843519     Time : 128166624211962704.000000    Size : 65536
[Application] OP : Read     Location : 26843519     Time : 128166624211968352.000000    Size : 65536
[Application] OP : Read     Location : 26843519     Time : 128166624212755744.000000    Size : 49152
[Application] OP : Read     Location : 26843519     Time : 128166624212868368.000000    Size : 20480
[Application] OP : Read     Location : 26843519     Time : 128166624212905984.000000    Size : 45056
[Application] OP : Read     Location : 26843519     Time : 128166624213527424.000000    Size : 65536
[Application] OP : Read     Location : 26843519     Time : 128166624213988224.000000    Size : 65536
[Application] OP : Read     Location : 26843519     Time : 128166624213996448.000000    Size : 65536
[Application] OP : Read     Location : 26843519     Time : 128166624232905616.000000    Size : 65536
[Application] OP : Read     Location : 26843519     Time : 128166624242878896.000000    Size : 57344
[Application] OP : Read     Location : 3608576     Time : 128166624242935248.000000    Size : 57344
[Application] OP : Read     Location : 26843519     Time : 128166624243149616.000000    Size : 65536
[Application] OP : Read     Location : 26843519     Time : 128166624243365008.000000    Size : 65536
[Application] OP : Read     Location : 26843519     Time : 128166624274398032.000000    Size : 32768
[Application] OP : Read     Location : 6320128     Time : 128166624295029088.000000    Size : 65536
[Application] OP : Read     Location : 26843519     Time : 128166624295087648.000000    Size : 49152

【问题讨论】:

  • 为什么你的printf()"%ul" 而不是"%lu"
  • 也许 1) 阅读 fscanf 的手册页 2) 检查其返回值
  • 这很奇怪,它们可以在 64 位上安装在 unsigned int 上,但你的似乎太严格了。你能发布你正在编译和运行它的架构吗?你能把生成的可执行文件的文件类型贴出来吗?
  • 始终检查类 scanf 函数的返回值。最后还要检查ferror的返回值。
  • @alvits - 这一点都不奇怪。 “64 位”是内存架构的一个特征,而不是(必然)整数类型大小的驱动程序。有 64 位实现具有 32 位 unsigned int(我不知道任何仅支持 16 位 unsigned int 的 64 位实现,但 C 和 C++ 标准实际上并没有阻止它要么)。

标签: c++ c


【解决方案1】:

如果有关于架构影响整数大小的问题,您可以使用stdint.h 提供的精确大小 整数表示以及inttypes.h 中的扫描和打印宏。例如,您的代码可以重写为:

#include <stdio.h>
#include <stdint.h>     /* for uintX_t       */
#include <inttypes.h>   /* for SCNtX & PRItX */

int main (int argc, char **argv) {

    double time;
    uint64_t location;          /* exact size variables */
    uint32_t req_size, temp; 
    char op_type[10];
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    /* using SCN with fscanf and PRI with printf */
    while (fscanf (fp, "%lf %s %" SCNu64 " %" SCNu32 " %" SCNu32 "", 
                &time, op_type, &location, &req_size, &temp) == 5)
        printf ("[Application] OP : %s    Location : %10" PRIu64 "   "
                "  Time : %.0lf    Size : %5" PRIu32 "\n", op_type, 
                location, time, req_size);

    if (fp != stdin) fclose (fp);     /* close file if not stdin */

    return 0;
}

这将消除任何存储大小差异。

使用/输出示例

$ ./bin/readloc <dat/location.txt
[Application] OP : Read    Location :  383496192     Time : 128166477394345568    Size : 32768
[Application] OP : Read    Location :    2822144     Time : 128166483087163648    Size : 65536
[Application] OP : Read    Location : 3221266432     Time : 128166620794097840    Size :  4096
[Application] OP : Read    Location :    3354624     Time : 128166624207799328    Size : 49152
[Application] OP : Read    Location :    2961408     Time : 128166624207887072    Size : 57344
[Application] OP : Read    Location :  368979968     Time : 128166624210238736    Size : 65536
[Application] OP : Read    Location :  395730944     Time : 128166624211812800    Size : 65536
[Application] OP : Read    Location :  442093568     Time : 128166624211962704    Size : 65536
[Application] OP : Read    Location :  437964800     Time : 128166624211968352    Size : 65536
[Application] OP : Read    Location :  396734464     Time : 128166624212755744    Size : 49152
[Application] OP : Read    Location :  386232320     Time : 128166624212868368    Size : 20480
[Application] OP : Read    Location :  398438400     Time : 128166624212905984    Size : 45056
[Application] OP : Read    Location :  378523648     Time : 128166624213527424    Size : 65536
[Application] OP : Read    Location :  404738048     Time : 128166624213988224    Size : 65536
[Application] OP : Read    Location :  404475904     Time : 128166624213996448    Size : 65536
[Application] OP : Read    Location :  381739008     Time : 128166624232905616    Size : 65536
[Application] OP : Read    Location :  439144448     Time : 128166624242878896    Size : 57344
[Application] OP : Read    Location :    3608576     Time : 128166624242935248    Size : 57344
[Application] OP : Read    Location :  386646016     Time : 128166624243149616    Size : 65536
[Application] OP : Read    Location :  398176256     Time : 128166624243365008    Size : 65536
[Application] OP : Read    Location :  397676544     Time : 128166624274398032    Size : 32768
[Application] OP : Read    Location :    6320128     Time : 128166624295029088    Size : 65536

查看一下,试一试,如果您有任何问题,请告诉我。

【讨论】:

  • David C,您的代码在我的系统中运行良好。但是,即使我使用 uint64_t,我的代码仍然存在问题。你能帮我解决一下潜在的问题吗?
  • 当然,我今晚再过几个小时。确保您已发布完整的当前代码(只需将其添加到问题的末尾)以及您收到的任何错误。我去看看。
【解决方案2】:

您的(更新的)代码对我有用。无论如何,除非您使用非常奇怪的架构,否则整数大小不是问题。第一个出错的值是 383,496,192,可以用 28 位表示 (2^29 = 536,870,912)。

【讨论】:

    猜你喜欢
    • 2013-05-04
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多