【问题标题】:fscanf reading problemfscanf 读取问题
【发布时间】:2010-11-06 15:37:32
【问题描述】:

对不起,也许这是个愚蠢的问题。

我有一个这样的文件:

36 146 10 53 240 133 104 28 51 81 124 ...

所以我想从程序中读取数字,所以我这样做了:

....一些功能.....

int i;
    unsigned char key[16];
    FILE *fp;

printf ("\n ------ \n");

// open filename 
fp = fopen("key.txt","a");

printf("reading 128 bit key:\n");
for (i = 0; i < 16; i++){
    fscanf(fp,"%d \t", &key[i]);
    printf ("%d \t", key[i]);
}

printf ("\n ------ \n");

fclose(fp);
return 0;

但是当程序在屏幕上打印结果时,我会得到:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 .....

有什么想法吗?

【问题讨论】:

    标签: c scanf


    【解决方案1】:

    您需要注意读取的数据量。您的循环将进行 16 次迭代,每次都尝试将签名的 int 写入“密钥”。在 32 位机器上执行此操作超过 4 次,您会得到未定义的行为,因为您将在分配的 16 位(16 个字符)之外写入。通过使用 unsigned int 代替你就可以了。

    不需要格式字符串中的制表符,因为空格将匹配任何空格。

    int i;
    unsigned int key[16]; // char -> int
    FILE *fp;
    
    printf ("\n ------ \n");
    
    // open filename 
    fp = fopen("key.txt","r"); // a -> r
    
    printf("reading 128 bit key:\n");
    for (i = 0; i < 16; i++){
        if (fscanf(fp,"%d ", &key[i]) == 1){ // tab removed. 
            printf ("%d \t", key[i]);
        } else {
            printf("Error reading key.\n");
        }
    }
    
    printf ("\n ------ \n");
    
    fclose(fp);
    return 0;
    

    要回答您的问题,零的原因是您使用“a”打开文件,即追加。应使用“r”表示读取。

    【讨论】:

      【解决方案2】:

      生日,

      我再次通过 K&R 获得乐趣,所以我只是想我会使用指针算法重写你的程序,打开文件的读取模式,并检查 fscanf 是否真的读取了一些东西。

      HTH

      干杯,

      #include <stdio.h>
      
      int main() {
      
          unsigned int i, res, key[16];
          unsigned int *val = key;
          char *key_file = "key.txt";
          FILE *fp;
      
          // open filename
          if ((fp = fopen(key_file,"r")) == NULL) {
              fprintf (stderr, "%s: unable to open file %s\n", argv[0], key_file);
              return 1;
          }
      
          printf ("------\n");
      
          printf("reading 128 bit key:\n");
          while (fscanf(fp, "%u", val) == 1) {
              printf ("%u ", (*val++));
          }
      
          printf ("\n ------\n");
      
          fclose(fp);
      
          return 0;
      
      }
      

      【讨论】:

      • 您可能还想在使用之前测试该文件是否已实际打开。
      • @Neil,完成。感谢您的建议。
      【解决方案3】:

      不直接回答您的问题,但最好从不使用fscanf(),因为几乎可以肯定,失败会使文件指针处于未知状态。

      优选的解决方案是使用其中一种行读取函数(如fgets() 或类似函数),然后使用它提供给您的字符串sscanf()

      这有两个好处:

      • 你会知道函数指针的状态。
      • 你可以sscanf()这个字符串,直到你认出它为止。

      此外,当您scanf()"%d" 时,它会将一个整数存储到您的字符数组中。这并不是您真正想要的,因为基础类型几乎可以肯定是不同的大小。扫描字符或将基础数据类型更改为整数。

      而且最重要的是,您是以追加而不是读取模式打开文件。

      【讨论】:

        【解决方案4】:

        您需要以读取模式打开文件:

        p = fopen("key.txt","r");
        

        检查 fscanf() 的返回值以查看读取是否真正成功也是一个好主意。

        编辑:我刚刚注意到:

        unsigned char key[16];
        

        应该是一个整数数组(我认为-从代码中不太清楚“key”的含义是什么):

        int key[16];
        

        【讨论】:

        • 传递给 scanf 的格式字符串包含“%d”,所以键必须是 int[] 而不是 char[]
        • 是的,但替代方案显然是更改格式字符串!真的不清楚提问者想要代码做什么。
        【解决方案5】:

        一些更正:

          int i;
          unsigned char key[16];
          FILE *fp;
        
          printf ("\n ------ \n");
        
          // open filename 
          fp = fopen("key.txt","r"); // <--- Read mode
        
          printf("reading 128 bit key:\n");
          for (i = 0; i < 16; i++){
              fscanf(fp,"%c \t", &key[i]); // <--- %c, read it char by char
              printf ("%d \t", key[i]);
          }
        
          printf ("\n ------ \n");
        
          fclose(fp);
        

        【讨论】:

        • 非常感谢,现在它可以工作了,主要问题是文件没有以读取模式打开
        • 在“for”循环中,他想一次填充“key”数组一个字符。所以他不能使用“%d”。
        【解决方案6】:

        为什么你的 fscanf 中有一个空格和一个制表符?输入是否有制表符或空格? 您还打开了文件以附加而不是阅读。 (“a”用于追加,“r”用于读取)

        您能否更改您的 fscanf 以匹配您的输入并重试?

        【讨论】:

          猜你喜欢
          • 2016-07-27
          • 1970-01-01
          • 2014-04-06
          • 1970-01-01
          • 2017-12-04
          • 1970-01-01
          • 2015-08-04
          • 1970-01-01
          相关资源
          最近更新 更多