1
votes

sorry, perhaps this is a stupid question.

I have a file like this:

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

so I want to read the numbers from a program, so I do:

.... some function .....

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;

but when the program prints the results on screen I just get :

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

any ideas ?

6

6 Answers

4
votes

You need to open the file in read mode:

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

It's also a good idea to check the return value of fscanf() to see if the read actually succeeded.

Edit: I just noticed:

unsigned char key[16];

should be an array of ints (I think - it's not very clear from the code what the meaning of "key" is):

int key[16];
3
votes

Not directly answering your question but it's a good idea to never use fscanf() due to the near-certainty that failure will leave the file pointer in an unknown state.

The preferable solution is to use one of the line reading functions (like fgets() or similar) and then sscanf() the string that it gives you.

That has two advantages:

  • you will know the state of the function pointer.
  • you can sscanf() the string to your heart's content until you recognize it.

In addition, when you scanf() a "%d", it stores an integer into your character array. That's not really what you want since the underlying types are almost certainly different sizes. Either scan characters or change the underlying data type to integers.

And to top that off, you're opening the file in append rather than read mode.

0
votes

Why do you have a space and a tab in your fscanf? Does the input have a tab or a space? Also you have opened your file for appending not for reading. ("a" is for append, "r" is for read)

Can you change your fscanf to match your input and try again?

0
votes

Some corrections:

  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);
0
votes

G'day,

I've been having fun working my way through K&R again so I just thought I'd rewrite your program using pointer arithmetic, read mode for the file open, and checking that fscanf actually read something.

HTH

cheers,

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

}
0
votes

You need to be careful on how much data you read. Your loop will go on for 16 iterations and each time try to write a signed int to 'key'. Do this more than 4 times on a 32 bit machine and you get undefined behaviour since you would write outside the 16 bits you allocated (16 chars). By using an unsigned int instead you are ok.

The tab character in the format string is not needed as the space will match any whitespace.

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;

To answer your question the reason for the zeros is that you open the file with "a" i.e. append. "r" for read should be used.