fscanf 将指针更改为负值

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

我有文件的代码,开头有数字,我必须阅读,然后是字母。我需要打印索引与文件开头的数字相对应的字母,而索引是从文件开头开始的。例如,一开始我有 10 我需要打印文件的第十个字符。问题是,当我第一次使用 fscanf 时,它给出的负索引正好是 -7(其中值为 -7),所以它只执行一次,因为然后 fscanf 返回 0,为什么?

#include <stdio.h>

int main() {
    char letter;
    int num;
    long where;
    FILE *fp;
    if((fp = fopen("chance.txt","r"))==NULL) {
        printf("File corrupted");
        return 1;
    }

    rewind(fp);
    while (fscanf(fp,"%d",&num)==1){
        where = ftell(fp);
        fseek(fp,num,SEEK_SET);
        letter = (char)fgetc(fp);
        printf("%c", letter);
        fseek(fp,where,SEEK_SET);
    }
    fclose(fp);
    return 0;
}

文件可能看起来像这样

30 23 42
32
"Some text"

虽然整个文件永远不会短于最大索引

需要在文件开头逐个打印字母,其中位置是数字,例如我得到数字10,它将在文件的第十个位置pfint vhar 始终以数字开头,然后是文字

最大的问题是 ftell 第一次使用时返回值 -7,所以循环永远不会继续

我希望在第一个和后面的循环转换中能够读取下一个数字,然后打印与它们相对应的字符

c file scanf ftell
1个回答
0
投票

代码中的问题与 fseek 和 ftell 与文件位置指示器的结合使用有关。当您使用 fseek(fp, num, SEEK_SET); 时,它将文件位置指示器设置为从文件开头算起的绝对位置 num。但是,当您稍后使用 ftell(fp) 获取当前文件位置时,它会返回从文件开头到当前位置的偏移量。这意味着 where 不是绝对位置而是偏移量,从而导致意外的行为。

这是代码的修改版本,应该可以正常工作:

#include <stdio.h>
int main() {
  char letter;
  int num;
  FILE *fp;
 
  if((fp = fopen("chance.txt", "r")) == NULL) {
    printf("File corrupted");
    return 1;
  }

  rewind(fp);

  while (fscanf(fp, "%d", &num) == 1) {
      fseek(fp, num, SEEK_SET);
      letter = (char)fgetc(fp);
      printf("%c", letter);
      fseek(fp, 0, SEEK_SET);  // Reset the file position to the beginning
  }

  fclose(fp);
  return 0;

}

在这段修改后的代码中,读取数字并使用 fseek 移动到指定位置后,我添加了 fseek(fp, 0, SEEK_SET);在下一次迭代之前将文件位置重置为文件的开头。这样,您可以确保后续的 ftell 正确地为您提供从文件开头开始的绝对位置。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.