【问题标题】:Writing my own version of 'fgets()' in C用 C 编写我自己的“fgets()”版本
【发布时间】:2016-09-20 01:57:49
【问题描述】:

我想创建我自己版本的函数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;
}

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

【问题讨论】:

  • 标准fgets()不打开文件;除非你受到导师的责难,否则你也不应该。
  • 请注意,while (sizeof(my_string) &lt; bytes …) 的循环是错误的。大小是指针中的字节数(可能是 4 或 8)并且不会改变。
  • my_string[i] != '\n' : 值(my_string[i]) 尚未确定。
  • &lt; bytes 应该是&lt; bytes - 1
  • 第三个参数类型是 const char *filenamestdinFILE*

标签: c file fgets


【解决方案1】:

你的fgets()实现有很多主要问题:

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

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

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

  • 您不会在文件末尾返回 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] = '\0'; //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;
}

【讨论】:

  • 非常感谢您的详细解释,我会仔细阅读。
猜你喜欢
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多