6

首先,这不是家庭作业。只是想了解为什么我会看到我在屏幕上看到的内容。

下面的东西(我自己的工作)当前需要一个输入文件并将其作为二进制文件读取。我希望它将读取的每个字节存储在一个数组中(供以后使用)。为简洁起见,输入文件 (Hello.txt) 仅包含“Hello World”,没有撇号。

int main(int argc, char *argv[]) {

    FILE *input;
    int i, size;
    int *array;

    input = fopen("Hello.txt", "rb");
    if (input == NULL) {
        perror("Invalid file specified.");
        exit(-1);
    }

    fseek(input, 0, SEEK_END);
    size = ftell(input);
    fseek(input, 0, SEEK_SET);

    array = (int*) malloc(size * sizeof(int));
    if (array == NULL) {
        perror("Could not allocate array.");
        exit(-1);
    }
    else {
        input = fopen("Hello.txt", "rb");
        fread(array, sizeof(int), size, input);
        // some check on return value of fread?
        fclose(input);
    }

    for (i = 0; i < size; i++) {
        printf("array[%d] == %d\n", i, array[i]);
    }

为什么在上面的 for 循环中使用 print 语句会导致输出看起来像这样

array[0] == 1819043144
array[1] == 1867980911
array[2] == 6581362
array[3] == 0
array[4] == 0
array[5] == 0
array[6] == 0
array[7] == 0
array[8] == 0
array[9] == 0
array[10] == 0

像这样

printf("array[%d] == %d\n", i, ((char *)array)[i]);

使输出看起来像这样(每个字符的十进制 ASCII 值)

array[0] == 72
array[1] == 101
array[2] == 108
array[3] == 108
array[4] == 111
array[5] == 32
array[6] == 87
array[7] == 111
array[8] == 114
array[9] == 108
array[10] == 100

? 如果我将它作为二进制文件读取并想逐字节读取,为什么不使用第一个打印语句获得正确的 ASCII 值?

在相关说明中,如果我发送的输入文件不是文本文档(例如 jpeg)会怎样?

抱歉,这完全是一件微不足道的事情,但我似乎无法弄清楚为什么

4

2 回答 2

7

这种行为并不奇怪:

  • 您有一个包含 11 个字符的文件。sizeof(char)是 1。
  • int现在你分配一个11 int的数组。sizeof(int)在你的机器上很可能是 4
  • 您指示fread最多读取 11int秒(最多 44 个字节)。因此,前 4 个字符将被读取为 anint并存储在中array[0],接下来的 4 个字符将存储在 中array[1]
    • 如果您检查了它的返回,fread它会告诉您它实际上只读取了 2 个元素(因为内容是 11 个字节,它只能读取 2int秒,并且最后 3 个剩余字节无法成功读取为int)。
  • 现在您遍历数组并打印int由前 4 个字符组成的数字。
  • 在您的替代解决方案中,您假装指向一个字符序列,因此数组索引只会增加 1 个字节的偏移量

内存布局基本上是这样的:

array[0]
|       array[1]
|       |
1 2 3 4 5 6 7 8 9 10 11
| |
| ((char *)array)[1]
((char *)array)[0]
于 2013-09-24T19:45:58.803 回答
4

您的 ftell 返回流的位置指示器的当前值。

它返回文件具有的字节数。并且您正在将文件读取为 int 4 字节的序列,当然后面的元素将为 0。有关更多详细信息,您正在从具有 size 字节的文件中读取 4 x size 字节。

您的数组应该是 char 类型。

就像是

char* array = malloc(sizeOfFile * sizeof(char));
if(array == NULL) {
  ...
}

fread(array, sizeOf(char), sizeOfFile, filePointer);
// ..

只是想法,而不是代码。希望这有帮助;

于 2013-09-24T04:32:09.193 回答