在C中编写我自己的'fgets()'版本

时间:2016-09-20 01:57:50

标签: c file fgets

我想创建自己的函数版本fgets()。 我试图这样做,但遇到了一些问题。 请告诉我哪里出错了。

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

char *my_fgets(char my_string[], int bytes, const char *filename) {
    int i = 0;
    FILE *fp;

    if ((fp = fopen(filename, "wb")) == NULL) {
        fprintf(stderr,"Couldn't open the file");
        return NULL;
    }

    while (sizeof(my_string) < bytes || my_string[i] != '\n')
        my_string[i++] = getc(fp);

    my_string[i] = '\0';        //adding NULL character at the end

    /*   using pointers
    char *p;
    for (p = array; p < array + bytes; p++)
        *p = getc(fp);    
    *p = '\0';  */    

    fclose(fp);
    return my_string;    
}

int main() {
    char my_string[15];
    int n;
    char *p;

    p = my_fgets(my_string, sizeof(my_string), stdin);    

    printf("\n%s", my_string);
    printf("\n%s", p);

    return 0;
}

我的输出没有运行,它立即崩溃。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:5)

fgets()实施存在许多重大问题:

  • 原型不正确:最后一个参数应该是流指针(FILE *),而不是文件名(const char *)。您使用stdin调用您的函数,这确实是一个流而不是文件名。编译器应该为这个错误发出警告。恕我直言这个警告应该是一个错误。启用所有编译器警告,不要忽略它们:gcc -Wall -W -Werror

  • 要打开文件以便作为文本阅读,您应该使用"r"的模式字符串,而不是"wb",这将截断文件,但由于该函数应该收到{{1这是一个有争议的问题。

  • FILE *中的测试由于多种原因而不正确:您应该将while (sizeof(my_string) < bytes || my_string[i] != '\n')与数组大小进行比较,而不是将i与常量,指针大小和你应该比较从文件中读取的字节,而不是你尚未存储任何内容的sizeof(my_string)。此外,您应该使用逻辑和运算符(my_string[i])来组合这些测试,而不是逻辑或(&&)。

  • 最终的||应存储在目标数组中。

  • 您不会在文件末尾返回'\n'

  • 您不处理零缓冲区大小的特殊情况。

以下是改进版本:

NULL