在此代码中工作的 C FILE fgets 函数

C FILE fgets function working in this code

在我的代码中,我有一个名为 "f1.txt" 的文件,该文件中的文本是一个字符串 "robin singh hero"

我已经创建了一个大小为 [10] 的字符串 [b]str[/b] 和一个 FILE 类型的指针变量 *fp 然后通过 fopen 函数将我的文件 "f1.txt" 的地址分配给这个指针.

然后我使用了带有这三个参数(字符串、大小、文件指针)的 fgets 函数

#include <stdio.h>

void main()
{
  char str[10];
  FILE *fp;

  fp = fopen("f1.txt","r");

  if(fp == NULL)
  {
  printf("File does not exists");
  exit(1);
  }

  while (fgets(str,8,fp)!=NULL){
    printf("%s",str);
  }
  printf("\n");
  fclose(fp);
  puts(str);
  puts(str);
}

我提到了大小 8,所以这意味着 fgets 将从我的文件中读取前八个字符 (robin sin) 并将其存储到我的字符串中,该字符串的大小为 10,并且仍然有 2 个字节的 space 在我的左边细绳。然后直到我的文件达到 null 为止,它会复制接下来的 8 个字符(gh hero)。

所以我想知道这个: 1.现在还剩6个字,但实际结果是(robin singh hero)

  1. 当只剩下 6 个字符时,第二步发生了什么。

  2. 我想知道在这个 while 循环结束后我的字符串 str 发生了什么。所以我做了 puts(str) 并且在终端中得到了这个值 (ro)。

下面是这段代码的实际结果: 罗宾辛格英雄

ro

ro

正如您在问题中所述,文件 f1.txt 包含此内容

robin singh hero

现在当下面的代码被执行时

while (fgets(str,8,fp)!=NULL){
    printf("%s",str);
}

fgets()fp 指向的文件中读取大小减去一个字符,即 7 个字符并存储在 str 中。所以在第一次迭代中 printf() 语句打印

robin s

然后在第二次迭代中它再次尝试读取 7 字符即 printf() 语句打印

ingh he

然后它再次尝试读取 7 个字符,但只有 3 个字符(包括 \n,如果是的话)所以 printf() 语句打印

ro

现在是下面的代码段

printf("\n"); /* prints \n character on console */
fclose(fp); /* closes the file */
puts(str); /* when above while loop terminates str has ro in it, hence it prints ro on console */
puts(str); /* prints ro on console */

由于您调用了 puts() 两次,它会打印 ro 两次。

来自 fgets()

的手册页

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte (aq[=39=]aq) is stored after the last character in the buffer.

另请注意,void main() {} 不是标准的 main() 原型。你应该使用

int main(void) {

   return 0;
}

来自C标准 5.1.2.2.1程序启动

1 The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

int main(void) { /*...*/ }

or

with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

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