本周我的任务是创建一个程序,读取我教授发给我的数据文件。赋值说这个数据中有10个整数我需要写入数组,我已经完成但我不确定它是正确的还是只是垃圾数据。我将为此文件附加一个DL链接(它只有40字节)。我在下面创建了一个程序,它将读取我需要的10个数字,但我怎么知道它是垃圾数据还是真正的交易。我每次都得到相同的数字,这表明我正在做这个吗?我希望将来使用任何长期技巧。
这是DL链接 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);
}
答案 0 :(得分: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
是32位(4字节)。此外,交换字节的原因是因为我的系统是小端的;这意味着12
是最不重要的8位,34
是次最重要的等等。
您可能希望将这些字节作为单个字节进行访问,您应该将Mystery
更改为char[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);
答案 1 :(得分:0)
首先,它应该指定如何将这些整数存储到文件中。
由于文件是40个字节,并且存在项目计数为10的规范,您可以假设它们存储为二进制数据,每个整数占用四个字节。
*我这样说是因为该文件可能是一个文本文件,整数存储为换行符分隔值:
10
13
4563
-32
等......
但是。在40个字节中,没有10个整数存储为文本的空间,所以假设它们是二进制数据。
此时我们还假设数据的字节顺序与程序编译和运行的体系结构相同。我不会再进一步了解更多信息,您可以谷歌搜索 big endian little endian
最后应该指定整数的大小。整数的大小可能因操作系统/体系结构而异:
请参阅What does the C++ standard state the size of int, long type to be?
但我们有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 );
}