C 用于读取特定大小的FGET

C 用于读取特定大小的FGET,c,input,fopen,fgets,C,Input,Fopen,Fgets,我试图编写一个程序,从命令行给出的文件名中读取一定数量的字符。以下是我所拥有的: #include <stdio.h> int main(int argc, char **argv) { int i = 0; FILE *f; char* fileName = argv[1]; char buf[40]; f = fopen(fileName, "r"); while(!feof(f)){ fgets(buf, 1

我试图编写一个程序,从命令行给出的文件名中读取一定数量的字符。以下是我所拥有的:

#include <stdio.h>

int main(int argc, char **argv)
{
    int i = 0;
    FILE *f;
    char* fileName = argv[1];
    char buf[40];

    f = fopen(fileName, "r");

    while(!feof(f)){
        fgets(buf, 10, f);
        printf("%s\n", buf);

    }
    fclose(f);

    return 1;
}
在这种情况下,我需要前10个字符,然后是下10个字符,以此类推,直到文件结束。然而,当我运行这段代码时,它实际上并没有给我正确的输出。我也尝试了11个,因为文档中说fgets读取n-1个字符,但这也不起作用。一开始读了一些东西,但后来什么也没读,这只会给我一堆空白。你知道怎么了吗


谢谢

您正在寻找的功能是fread,如下所示:

fread(buf, 10, 1, f);
fgets用于读取最大长度的行。如果希望一次读取10个字符,而不考虑换行,则可能需要使用fread:

无论哪种方式,你肯定不想使用而!菲奥夫。您可能需要以下内容:

int main(int argc, char **argv) { 
    char buf[40];
    FILE *f;
    if (NULL == (f=fopen(argv[1], "r"))) {
        fprintf(stderr, "Unable to open file\n");
        return EXIT_FAILURE;
    }

    size_t len;
    while (0 < (len=fread(buf, 10, 1, f)))
        printf("%*.*s\n", len, len, buf);
    return 0;
}

如果您从printf格式字符串中删除\n,并且假设您希望基本上按原样回显整个文件,那么它几乎可以正常工作

我还将基于FGET循环…!=NULL,因为在fgets错误和点击EOF后,feof将返回一个真值,所以最后一次缓冲区已满将打印两次。您可以对代码进行一些小的更改,如下所示:

#include <stdio.h>

int main(int argc, char **argv)
{
    int i = 0;
    FILE *f;
    char* fileName = argv[1];
    char buf[40];

    f = fopen(fileName, "r");

    while(fgets(buf, 10, f))
        printf("%s", buf);

    fclose(f);

    return 0;
}

另外,正如其他人所说,虽然我花了太长时间来回答,但fread可能是一个更好的选择,因为fgets不一定要读10个字符;它会在每一行换行时停止,你不必一次读一行。

去掉feof,而是检查fgets的返回值。否则,它应该工作得相当好,除非您希望通过11来读取最多10个字节。保存字符串终止符需要一个字节。谢谢你的评论,但为了我的特殊作业,我必须使用fgets。@Kevin-fgets读取一行指定的字符数。如果您的行短于10个字符,您将仅读取该行。如果你想读取二进制数据,你可能会得到到处都是的结果。@LeonardoHerrera-你能解释一下为什么二进制数据不能正常工作吗?@Kevin-在处理文本时,一些字符字节有特殊的意义。这不适用于二进制数据。当我尝试使用while循环部分时,它告诉我printf行的格式参数太少。Seg出错。给我的文件是一个二进制文件。很抱歉造成这种混乱。它的文本中有一串^@^@。。我假设这表示空字符。@Kevin:二进制数据不应导致seg错误,但要获得有意义的打印输出,您可能需要执行类似十六进制转储的操作,只打印可打印字符字母、数字、标点符号的字符表示,而不打印大多数控制字符等。您还希望在打开二进制文件时使用rb作为模式字符串,尽管在某些操作系统上没有区别,但您仍然希望这样做是为了可移植性。我在没有\n的情况下尝试了它,它只是我之前得到的任何不正确的输出减去换行符。我还更改了feof,但仍然不走运。@Kevin您能提供一个输入文件示例吗?我使用这个实际的代码作为输入,它正确地打印出来。你不是想打印二进制文件吧?我是想用二进制文件。很抱歉,我没有在描述中详细说明。这可能就是为什么所有答案都不起作用的原因。文件基本上是单词,周围有^@^@^@^@^@我认为这就像一个空字符。除此之外,没有其他非文本、数字或其他任何东西。@Kevin你的老师希望如何输出这些内容?打印时,只有二进制文件中的实际字符串才可读。如果您有一个值为1的字节,则不会在终端中打印“1”。请看,ASCII字符“1”的值为0x31或49(十进制)。除非您创建某种十六进制查看器之类的东西,否则二进制文件将主要显示垃圾。或者你想复制一份文件?无论哪种方式,对二进制数据使用FGET都没有意义。