0

我本周的任务是创建一个程序来读取我的教授发给我的数据文件。作业说我需要将这个数据中的 10 个整数写入一个数组,我已经完成了,但我不确定它是正确的还是只是垃圾数据。我将附上这个文件的 DL 链接(它只有 40 字节)。我在下面创建了一个程序,它将读取我需要的 10 个数字,但我怎么知道它是垃圾数据还是真实交易。我每次都得到相同的数字,这是否表明我做对了?我将来使用的任何长期提示也将不胜感激。

这是 DL 链接 神秘数据

#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);
}
4

2 回答 2

0

首先,如果您的意思是Mystery在通话后打印地址fread,您应该使用%p. 其次,也许以十六进制打印会帮助您看到问题:

% 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
%

这些值以整数形式串在一起,并且按字节反转。它们被串在一起,因为您将它们作为整数读取:

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

从这里我们看到int我的编译器中的 s 是 32 位(4 字节)。此外,交换字节的原因是因为我的系统是小端的;这意味着12是最低有效的 8 位,34是下一个最高有效位,等等。

您可能希望将这些作为单独的字节访问,您应该将其更改Mysterychar[10]. 并且可能将其扩大以确保您有足够的空间。最后,您要检查 的返回值fread,它将告诉您实际读取了多少字节。


Fread如此声明:

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

您传递的是正确的size,但不是传递的项目数nitems,而是传递的大小Mystery,即nitems*sizeof(int)。利用

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

或更好,

fread(Mystery, sizeof(Mystery[0]), sizeof(Mystery)/sizeof(Mystery[0]), myFile);
于 2013-10-25T14:38:35.703 回答
0

首先,它应该指定这些整数如何存储到文件中。

由于文件是 40 字节,并且有一个规范,即项目数为 10,您可以假设它们存储为二进制数据,每个整数占用 4 个字节。

*我这么说是因为该文件可能是一个文本文件,其中整数存储为换行符分隔值:

10

13

4563

-32

ETC......

但。在 40 个字节中,没有空间存储 10 个以文本形式存储的整数,所以假设它们是二进制数据。

在这一点上,我们还假设数据的字节序与您的程序将被编译和运行的架构相同。我不会对此进行进一步讨论,有关更多信息,您可以在 Google 上搜索big endian little endian

最后应该指定整数的大小。整数的大小可能因操作系统/架构而异:

请参阅C++ 标准规定 int、long 类型的大小是什么?

但是我们有 40 个字节,我们知道我们有 10 个整数。在文件中,int 是每个数字的 4 个字节。

您可以检查是否与您的架构匹配:

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

并查看输出。

回到你的代码有一些需要调整的地方。看评论...

#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 );
}
于 2013-10-25T15:00:51.300 回答