【问题标题】:Not being printed out when using fgets使用 fgets 时未打印出来
【发布时间】:2021-11-28 19:09:45
【问题描述】:

我正在学习 C 中的文件输入/输出。但有些东西我不明白。
我正准备使用 fgets打印 [words.txt] 中的简单句子,但它不起作用。

[words.txt]如下:

This speech caused a remarkable sensation among the party.

我的代码是:

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

int main()
{
    char *buffer = malloc(100);
    memset(buffer, 0, 100);

    FILE *fp = fopen("words.txt", "r");

    fgets(buffer, sizeof(buffer), fp);

    printf("%s\n", buffer);

    fclose(fp);

    free(buffer);

    return 0;
}

输出是“这个sp”

我以为我的代码没有问题,但输出结果出乎意料。

我的意思是, 为什么没有打印出整个字符串?
另外,这个输出字符串的原因是什么?
(似乎没有迹象表明这段代码会有7个字符,即“This sp”)

【问题讨论】:

  • 旁注:memset(buffer, 0, 100); 行是多余的,因为fgets 会将终止的空字符写入buffer

标签: c memset file-pointer


【解决方案1】:

您的缓冲区被声明为char* 而不是固定大小的数组,因此sizeof(buffer) 为8,因此读取和打印了7 个字符(加上'\0')。 sizeof 不知道你向malloc 询问了多少字节。我认为当您开始学习指针并意识到数组像指针一样工作但又不完全一样时,这是最令人困惑的事情。

解决方案:

fgets(buffer, 100, fp);

或者

char buffer[100];
fgets(buffer, sizeof(buffer) fp);

【讨论】:

    【解决方案2】:

    由于您将buffer 声明为char *buffer,因此它不是一个数组。相反,它只是一个指针。

    表达式sizeof buffer 将计算指针本身的大小,而不是指针指向的对象的大小。由于指针的大小通常为 32 位或 64 位,因此表达式 sizeof buffer 将计算为 48。在你的情况下,它似乎是8

    如果你已经声明 buffer 而不是这样

    char buffer[100];
    

    那么buffer 将不是一个指针,而是一个数组,而表达式sizeof buffer 的计算结果将是100

    在您的情况下,使用malloc 而不是数组没有任何问题。但是,如果你使用malloc,你必须自己记住分配的内存大小。您不能为此使用 sizeof 运算符。

    您可以为此使用预处理器宏,而不是在代码中的多个位置写入数字 100

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define ALLOCATION_SIZE 100
    
    int main()
    {
        char *buffer = malloc( ALLOCATION_SIZE );
        memset(buffer, 0, ALLOCATION_SIZE );
    
        FILE *fp = fopen("words.txt", "r");
    
        fgets(buffer, ALLOCATION_SIZE, fp);
    
        printf("%s\n", buffer);
    
        fclose(fp);
    
        free(buffer);
    
        return 0;
    }
    

    这样做的好处是,如果您决定将数字 100 更改为其他数字,您只需在代码中的一处而不是多个地方更改数字。

    【讨论】:

    • 哦,非常感谢!!!!顺便说一句,有没有办法在执行程序时知道分配内存的大小而不使用这种方式或记住?
    • @yJ.:这在 ISO C(即通用标准)中是不可能的。但是,个别操作系统可能会提供一种方法来执行此操作。请参阅this question 了解更多信息。但我不建议这样做,除非作为学术练习。通常更容易记住分配的大小,例如将其存储到变量中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多