函数 —— fgets()

17 篇文章 0 订阅
16 篇文章 1 订阅
//char *fgets(char *str, int n, FILE *stream)
/*功能:
 *从文件指针stream中读取n-1个字符,存到以str为起始地址的空间里,直到读完一行,如果成功则返回str的指针,否则返回NULL。*/
/*参数:
 * str -- 这是指向一个字符数组的指针,该数组存储了要读取的字符串。
 * n -- 这是要读取的最大字符数(包括最后的空字符)。通常是使用以 str 传递的数组长度。
 * stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了要从中读取字符的流。*/
/*返回值:
 * 成功返回buf,失败或者读到文件结尾返回NULL
 * */
/*结束的标志:
 * 当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定*/
/*出错终止的判断:
 *不能直接通过fgets的返回值来判断函数是否是出错而终止的,应该借助feof函数或者ferror函数来判

 * */

#include <stdio.h>
#include <string.h>

int main()
{
        FILE *fp;
        char str[60];
        int len;
        char str_1[60] = "This is test file!";
        
        printf("文件中文本内容:str_1 = %s\n",str_1); 
        printf("文件中文本长度:strlen(str_1) = %d\n",strlen(str_1)); 
        
        /* 打开用于读取的文件 */
        fp = fopen("file.txt" , "r");
        if(fp == NULL) {
                perror("打开文件时发生错误");
                return(-1);
        }
        printf("strlen(str) = %d\n",strlen(str));
        printf("sizeof(str) = %d\n",sizeof(str));
//是因为fgets(str,n,fp)函数中,n为求得到的字符,但只能从fp指向的文件输入n-1个字符,然后在最后加上一个'\0'字符,因此得到的字符串有n个字符,把它们放到str的首地址。
//所以实际上len-1才是我们希望看到的数目
//注意:当n的长度小于字符串的长度时候,len 就是我们看到的数目。
        if( fgets (str, 60, fp)!=NULL ) {
                /* 向标准输出 stdout 写入内容 */
                //puts(str);    
                len = strlen(str);
                printf("str = %s  len = %d\n",str,len-1);
        }
        fclose(fp);

        return(0);
}
/*       结果
 * 当n=60 > 18 时候:str为 This is test file!
 *      str长度应为18;len的值为19;实际上len-1是我们希望看到的数目,此时len-1=18
 *      :原因:n大于该行的字符总数加2(多出来的两个,一个保存文件本身的'\n'换行,一个保存字符串本身的结束标识'\0')
 * 当n=7 < 18时候:str为 This i
 *      str长度为应6;len的长度为6;实际上len是我们希望看到的数目,此时len-1=5
 *      :原因:n小于该行字符总数,读取文件的指针会偏移至当前读取完的这个字符之后的位置。也就是第二次再用fgets()读取文件的时候,则会继续读取其后的字符
 * */
  例:

  如果一个文件的当前位置的文本如下

  Love, I Have

  Since you can do it.

  如果用fgets(str1,6,file1);去读取

  则执行后str1 = "Love," ,读取了6-1=5个字符

  这个时候再执行fgets(str1,20,file1)则执行后str1 = " I Have\n"

  而如果

  fgets(str1,23,file1);

  则执行str1="Love ,I Have" ,

    读取了一行(包括行尾的'\n',并自动加上字符串结束符'\0'),当前文件位置移至下一行,虽然23大于当前行上字符总和,可是不会继续到下一行。而下一次调用fgets()继续读取的时候是从下一行开始读。
  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个有趣的编程问题。这里是一个可能的实现: ``` #include <setjmp.h> #include <stdio.h> #define MAX_TRIES 3 jmp_buf env; int tries = 0; char* tfgets(char* str, int n, FILE* stream) { char* ret = fgets(str, n, stream); if (ret == NULL) { return ret; } if (strcmp(str, "secret") == 0) { longjmp(env, 1); } return ret; } int main() { char str[100]; if (setjmp(env) != 0) { printf("You've been locked out\n"); return 1; } while (tries < MAX_TRIES) { printf("Enter password: "); if (tfgets(str, 100, stdin) == NULL) { break; } if (strcmp(str, "password") == 0) { printf("Access granted\n"); break; } tries++; } if (tries == MAX_TRIES) { printf("Too many tries\n"); } return 0; } ``` 在这个实现,我们定义了一个 `tfgets` 函数,它与 `fgets` 函数具有相同的参数和返回值,但是如果用户输入了 "secret",则会立即跳转到 `env` 标记处。我们在 `main` 函数使用了一个循环来尝试多次输入密码,如果尝试次数超过了 `MAX_TRIES`,则会给出警告并退出程序。在循环,我们使用 `tfgets` 函数而不是 `fgets` 函数来获取用户输入。如果 `tfgets` 函数返回 `NULL`,则说明用户已经到达了文件末尾,循环也会退出。 这个实现使用了 `setjmp` 和 `longjmp` 函数来实现非本地跳转。`setjmp` 函数保存了当前程序状态并返回一个标记,`longjmp` 函数则可以使用该标记来恢复程序状态并跳转到指定位置。在这个实现,我们在 `main` 函数的循环使用了 `setjmp` 函数来保存程序状态,并在 `tfgets` 函数使用了 `longjmp` 函数来跳转到 `env` 标记处。如果用户输入了 "secret",则会触发这个跳转。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值