【问题标题】:My implementation of fgets reads actual content as fgets does but it reads garbage if NULL string is found in file?我的 fgets 实现像 fgets 一样读取实际内容,但是如果在文件中找到 NULL 字符串,它会读取垃圾?
【发布时间】:2015-12-01 19:24:41
【问题描述】:

我已经实现了自己的fgets(即myfgets)。当我的文件中有 NULL 字符串必须由 myfgets 函数读取时,它会打印所有字符串(好)但有一些垃圾(坏),但如果我使用预定义 fgets 则没有垃圾。以下是我的代码和文件内容,其中包含 NULL 字符串。

我的文件

hello word NULL 早上好 // 如果 NULL 被删除,那么它是好的

#include<stdio.h>
#include<stdlib.h>
char *myfgets(char *Buffer_address,int size,FILE *fp)
{
    register int c;
    register char  *I_help_Notify_IfNotRead;
    I_help_Notify_IfNotRead = Buffer_address;

    while(--size>0 && (c=getc(fp))!=EOF )
    {
        if((*I_help_Notify_IfNotRead++=c)=='\n')
            break;
       *I_help_Notify_IfNotRead='\0';
    }

    return ( c==EOF && I_help_Notify_IfNotRead == Buffer_address ) ? NULL : Buffer_address;
}

int main()
{
    char ch[100];
    FILE *fp ;
    fp=fopen("myfile","r");
    char * pp=(myfgets(ch,100,fp));
    printf("%s",pp);

    exit(EXIT_SUCCESS);  // No need to close(fp) because exit does for us
}

输出:

hello word NULL Good Morning (good)

E����[�s^� (garbage)    // Why am I getting this but not with predefine fgets?

【问题讨论】:

  • *I_help_Notify_IfNotRead='\0'; 应该在循环之后。此外,如果您的文件为空,则行为未定义(c 未设置);只需删除c==EOF &amp;&amp;。 NULL 是指一个 NUL 字符吗?

标签: c file null fgets


【解决方案1】:

您对字符串进行空终止的逻辑已损坏。您在每个字符 除了 最后一个字符之后写入一个 NUL 字节。将写入 NUL 的行移到循环之后。

顺便说一句,我见过比I_help_Notify_IfNotRead 更糟糕的变量名,但并不常见。 out 出了什么问题?

【讨论】:

    【解决方案2】:

    空字符未附加在正确的点@rici@Jim Balter。这是主要问题。建议

    if (size > 0) {   
      while(--size>0 && (c=getc(fp)) != EOF) {
        *I_help_Notify_IfNotRead++ = c;
        if (c == '\n') break;
      }
      *I_help_Notify_IfNotRead = '\0';
    }
    

    角落案例问题:

    如果size == 1,则不写入空字符。 (固定在上面)

    myfgets() 不满足:“如果在操作过程中发生读取错误,...返回一个空指针。”也许:

    if (c == EOF) {
      if (ferror(fp)) return NULL;
      if (feof(fp) && I_help_Notify_IfNotRead == Buffer_address) return NULL;
    }
    return Buffer_address;
    

    【讨论】:

    • 是的,我同意未附加 NULL 字符,但您的第二条语句“如果在操作期间发生读取错误。返回空指针”但上面的 myfgets 将返回 NULL.in while loop getc()将读取的字符作为无符号字符转换为文件末尾的 int 或 EOF 或错误,并且在三元运算符中检查“c”不是吗?
    • @user4950013 EOF 在文件结束或出现输入错误时返回。如果返回了 EOF 并且没有读取任何内容,则您的代码将返回 NULL。根据规范,如果由于输入错误而返回 EOF,则无论先前读取的字符数如何,fgets() 都会返回 NULL
    • @user4950013 顺便说一句,不要说“NULL char”,而是使用“null character”或'\0'。为NULL保存“NULL”,即“空指针常量”。
    猜你喜欢
    • 1970-01-01
    • 2020-09-05
    • 2021-12-15
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    相关资源
    最近更新 更多