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

Writing my own version of 'fgets()' in C

我想创建我自己的函数版本 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] = '[=11=]';        //adding NULL character at the end

    /*   using pointers
    char *p;
    for (p = array; p < array + bytes; p++)
        *p = getc(fp);    
    *p = '[=11=]';  */    

    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;
}

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

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

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

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

  • while (sizeof(my_string) < bytes || my_string[i] != '\n') 中的测试不正确的原因有很多:您应该将 i 与数组大小进行比较,而不是 sizeof(my_string),它是一个常量,大小一个指针,你应该比较从文件中读取的字节,而不是 my_string[i] 你还没有存储任何东西。此外,您应该使用逻辑与运算符 (&&) 来组合这些测试,而不是逻辑或 (||).

  • 最终的 '\n' 应存储到目标数组中。

  • 你没有在文件末尾 return NULL

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

这是一个改进的版本:

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

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

    if (bytes <= 0)
        return my_string;

    while (i < bytes - 1 && ((c = getc(fp)) != EOF) {
        my_string[i++] = c;
        if (c == '\n')
            break;
    }
    my_string[i] = '[=10=]'; //adding NUL character at the end

    if (i > 0) {
        return my_string;
    } else {
        return NULL;  // no character read at end of file
    }
}

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

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

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

    return 0;
}