tags:

views:

705

answers:

7

Hi,

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 ?

A: 

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?

hhafez
+4  A: 

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];
anon
the format string passed to scanf contains "%d" so key has to be int[] and not char[]
Adrian Panasiuk
Yes, but the alternative is obviously to change the format string! It's really not clear what the questioner wants the code to do.
anon
+2  A: 

please check the return value of fscanf.

arsane
A: 

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);
Nick D
why the tabs in the fscanf? and why reading char by char?
hhafez
thanks alot, now it's working, the main problem was that the file was not opened in read mode
In the "for" loop he wants to fill "key" array one char at a time. So he can't use "%d".
Nick D
+2  A: 

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.

paxdiablo
A: 

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;

}
Rob Wells
You might like to also test that the file was actually opened before you use it.
anon
@Neil, Done. Thanks for the suggestion.
Rob Wells
A: 

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.

Key