0

My assignment this week is to go create a program that reads a data file that my professor sent to me. The assignment says there are 10 integers in this data that I need to write to an array, which I've done but I'm not sure if it's correct or just junk data. I will attach the a DL link for this file (it's only 40bytes). I've created a program below that will read off the 10 numbers that I need, but how do I know if it is junk data or the real deal. I am getting the same numbers everytime, is that an indication that I'm doing this correctly? Any long term tips for me to use in the future would be appreciated as well.

Here is the DL link mysteryData

#include <stdio.h>
#include <string.h>

int main(void)
{
  int i;

  FILE* myFile = NULL;

  myFile = fopen("mysteryData.dat", "rb");

  int Mystery[10] =
  { '\0' };

  if (myFile == NULL )
  {
    printf("Failed to open file\n");
  }
  else
  {
    fread(Mystery, sizeof(int), sizeof(Mystery), myFile);

    printf("%d\n", Mystery);
  }

  for (i = 0; i < 9; i++)
  {
    printf("%d\n", Mystery[i]);
  }
  fclose(myFile);
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
NSwanson7
  • 173
  • 1
  • 13
  • If unsure check the result of the `fread()` system call. – alk Oct 25 '13 at 14:37
  • @alk Can you give me an example I could use for this. I'm a beginner. – NSwanson7 Oct 25 '13 at 14:39
  • I'm sure you can read the documentation your own. Please see `man fread`: http://man7.org/linux/man-pages/man3/fread.3.html. – alk Oct 25 '13 at 14:39
  • looks good but fread(Mystery, sizeof(int), sizeof(Mystery), myFile); should be fread(Mystery, sizeof(int), 10/*count of elements*/, myFile); – kunal Oct 25 '13 at 14:45

2 Answers2

0

First, if you mean to print the address of Mystery after the fread call, you should use %p. Second, perhaps printing in hex will help you see the problem:

% echo $'\x12\x34\x56\x78\x9a\xbc\xde\xff' > mysteryData.dat
% ./test
0x7fff598cfae0 # %p
78563412       # %x
ffdebc9a
a # newline = 0x0a
0
0
0
0
0
0
%

The values are being strung together in the integers, and are bytewise-reversed. They are being strung together because you are reading them as integers:

12 34 56 78 9a bc de ff a0 00 00 00
^---------^ ^---------^ ^---------^

From this we see that ints in my compiler are 32 bits (4 bytes). Furthermore, the reason the bytes are swapped is because my system is little-endian; that means that the 12 is the least significant 8 bits, 34 is the next most significant, etc.

You probably want to access these as individual bytes, for which you should change Mystery to a char[10]. And maybe make it bigger to ensure you have enough space. Finally, you want to check the return value of fread, which will tell you how many bytes you have actually read.


Fread is declared thusly:

fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
                                 ^^^^         ^^^^^^

You are passing the right size, but instead of passing the number of items for nitems, you are passing the size of Mystery, which is nitems*sizeof(int). Use

fread(Mystery, sizeof(int), sizeof(Mystery)/sizeof(int), myFile);

Or better,

fread(Mystery, sizeof(Mystery[0]), sizeof(Mystery)/sizeof(Mystery[0]), myFile);
Kevin
  • 53,822
  • 15
  • 101
  • 132
  • Thank you, although this didn't change the results I was getting. It is a good thing for me to learn and use in the future. – NSwanson7 Oct 25 '13 at 14:41
  • Thanks, I was wondering is there any program that I can use to read binary so I can check my work in the future before turning in assingments. – NSwanson7 Oct 25 '13 at 14:47
  • @user2172993 updated with what I suspect is causing your confusion. – Kevin Oct 25 '13 at 15:05
  • You can check the bytes in a file with `hexdump` or `od`. – Kevin Oct 25 '13 at 15:06
0

First of all it should specified how these integers are stored into the file.

As the file is 40 bytes and there is a specification that the count of items is 10 you can assume that they are stored as binary data and each integer takes four bytes.

*I say that because the file may be a text file with integers stored as newline separated values:

10

13

4563

-32

etc......

But. In 40 bytes there is no space for 10 integers stored as text, so let's say they are in binary data.

At this point we assume also that the endianess of the data is the same of the architecture your program will be compiled and run. I won't go further on this, for more info you may google for big endian little endian

Finally it should be specified what is the size of an integer. The size of an integer may vary depending on the OS / architecture:

see What does the C++ standard state the size of int, long type to be?

But we have 40 bytes, we know we have 10 ints. Into the file the int is 4 bytes for each number.

You may check if that match with your architecture with:

printf("Here ints are %d bytes.\n", (int) sizeof(int));

and looking at the output.

Going back to your code thare are some things to be adjusted. See the comments...

#include <stdio.h>
#include <string.h>

int main (void)
{
    int i;

    int itemsRead; // we'll use that later...

    FILE* myFile=NULL;

    myFile=fopen("mysteryData.dat", "rb");

    int *Mystery = malloc (sizeof(int) * 10); // It's a better practice...
    //... to allocate the buffers/arrays you need instead of declaring them
    // statically. If your file grows up with millions of numbers your code
    // will still be scalable.

    if(!Mystery) // Just check the alloc succeeded
    {
        printf("Failed to allocate buffer\n");
    }

    if(myFile==NULL)
    {
        printf("Failed to open file\n");
        free( Mystery ); // Free the buffer
        return 0;        // Quit
    }

    itemsRead = fread(Mystery, sizeof(int), 10, myFile);
    // 2nd parameter is size of element
    // 3rd parameter is how many items
    // the function returns the items actually read

    // What is the file was shorter than expected?
    // Check we were able to actually read 10 items of 4 bytes each

    if( itemsRead < 10 )
    {
        printf("The file ended unexpectedly\n");
        free( Mystery ); // Free the buffer
        return 0;        // Quit
    }

    for (i=0; i<10; i++) // 10 Items: count from 0 to 9 so until i<10
    {
        printf("%d\n", Mystery[i]);
    }

    free( Mystery  );
    fclose( myFile );
}
Community
  • 1
  • 1
Paolo
  • 15,233
  • 27
  • 70
  • 91