为什么SEEK_CUR中的fseek使用随机字符作为空格?

问题描述 投票:1回答:1

有这个。

int main (void) {

    FILE *fp = fopen("txt2", "r+");

    rewind(fp); 
    fprintf(fp, "ab");
    fseek(fp,1L,SEEK_CUR); //trying to change offset to 1,2,3,...
    fprintf(fp, "cd");
    rewind(fp);

    for(int c;(c=getc(fp))!=EOF;)
        putchar(c);

    fclose(fp);

    return 0;
}

我想知道,如果 fseek 从当前的位置向前偏移,用空格或一些垃圾。我将给出的输出是 ^ 的地方,应该是空间。

fseek(fp,0L,SEEK_CUR)
->  abcd //yes, that is what I expect

fseek(fp,1L,SEEK_CUR)
-> abccd //not space -> 'c' char instead
     ^

fseek(fp,2L,SEEK_CUR)
-> abcdcd //'cd' are in addition (random chars?)
     ^^

fseek(fp,3L,SEEK_CUR)
-> abcdccd //'cdc' no it is probably not "random", they repeat
     ^^^

fseek(fp,100000000000L,SEEK_CUR)
-> abcdcdcdcdcdcdcdcdcd

fseek(fp,1000000000000000000000000L,SEEK_CUR0
->warning: integer constant is too large for its type
fseek(fp,1000000000000000000000000L,SEEK_CUR);

这是怎么回事与fseek移动?他们的模式上,"移动的char "将被制成?在这种情况下,根据接下来的 printf chars?cd). 我不太明白这种行为,如何用fseek按空格移动?我只知道用 rewind 为了执行正确的读取(在for循环中),在每次写之前和之后,但这并不能解释这种行为。谁能给个提示?

c io fseek
1个回答
0
投票

这就是实际发生的情况。

FILE *fp = fopen("txt2", "r+");   
// need to check (!=NULL) to assure `fopen()` was successful

rewind(fp);      
// `fopen()` places current position in file at beginning, so this call not needed

fprintf(fp, "ab");     
// current position now ==2 (starts at 0)

fseek(fp,1L,SEEK_CUR); //trying to change offset to 1,2,3,...
// current position now at 3 I.E. "ab?"

fprintf(fp, "cd");     
// current position now == 5 I.E. "ab?cd"

the value, at the '?' is what ever happened to be on the disk at (current position =2) position in the file

0
投票

啊哈,我知道是怎么回事了。它没有使用空格,而是使用NUL字节,这更符合预期,但在你的输出中却没有显示出来。

在你显示输出的示例代码中,把它改成。

    for(int c; (c = getc(fp)) != EOF;)
    {
        if (c == 0) c = '.';  // ADD ME
        putchar(c);
    }

现在每当有一个NUL字节的时候,它就会显示一个点,这代表了你所寻找到的洞。

从一个空的 txt2 文件和一个寻求偏移量为2,它显示。

ab..cd

因为你在终端上没有看到NUL字节,这让它看起来像所有的东西都被转移了,这让我挠了一下头。

EDIT建议:如果你能显示内容,你的帖子会更清楚。txt2 文件前后的变化,因为当NUL字节进入游戏时,这些变化是累积的,无法跟踪。

这样应该就可以了。

#include <stdio.h>

static void showfile(FILE *fp, const char *which)
{
    // using | characters to show the start and end of the buffer
    // in case there are trailing blanks involved.
    printf("File %s: |");
    for (int c; (c = getc(fp)) !=EOF;)
    {
        if (c == 0) c = '.';
        putchar(c);
    }
    printf("|\n");
}


int main (void) {

    FILE *fp = fopen("txt2", "r+");

    long offset = 3L;  //trying to change offset to 1,2,3,...
    printf("Running with offset = %ld\n", offset);

    showfile(fp, "before");

    rewind(fp);
    fprintf(fp, "ab");
    fseek(fp, offset, SEEK_CUR);
    fprintf(fp, "cd");
    rewind(fp);

    showfile(fp, "after ");

    fclose(fp);

    return 0;
}

然后运行它:

Running with offset = 2
File before: ||
File after : |ab..cd|

// rerun with previous file
Running with offset = 3
File before: |ab..cd|
File after : |ab..ccd|
© www.soinside.com 2019 - 2024. All rights reserved.