繁体   English   中英

来自初学者的另一个关于 C 中 fopen 的问题

[英]Another question about fopen in C from a beginner

我是 C 和一般编程的新手。 我想编写一个 C 程序,它将读取文本文件的内容并将其打印到控制台。 我有一个名为 test.txt 的文本文件,其中包含字符串“Hi”。 我使用以下代码创建了一个 C 程序:

#include <stdio.h>

main()
{
  FILE *myfile;
  myfile=fopen("test.txt", "r");
  printf("%s", myfile);
  fclose(myfile);
}

该程序编译正常(至少使用默认设置),但是当我运行程序时,字符串“Hi”没有出现。 你能帮我看看我做错了什么吗? 谢谢你。

另外,您有推荐的 C 参考网站吗? 我正在寻找一个包含 C 语言规范的网站,可能包括如何使用库函数的示例。

非常感谢您的宝贵时间。

安德鲁

卡内基·梅隆大学

您正在尝试在myfile的值指向的位置将字符串打印到控制台。 这显然是不正确的(如果您不知道为什么,那是因为%s需要一个char* ,而不是FILE* ,并且FILE*不指向文件的内容。)。

要从文件中读取数据,请使用fread

char buf[80] = {0}; // fill buf with NULLs
fread(buf, sizeof(char), 2, myfile); // read 2 bytes 

如果要将整个文件读入缓冲区,事情会稍微复杂一些,因为您必须确定文件的长度,然后在正确大小的堆上动态分配 memory 以保存文件。 在 cplusplus.com 的fread页面上有一个很好的教程。

这是因为您没有读取该文件。 要读取文件,可以使用freadfgets方法

要读取一行,使用fgets会更有意义,因为它会读取到行终止符( \n )。

char line[256]
fgets(line, sizeof(line), file);
printf("%s", line);

这是最安全的方法。

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

main()
{
  FILE *myfile;
  char buf[80];
  myfile=fopen("test.txt", "r");
  while(!feof(myfile)){
    memset(buf, 0, 80);
    fread(buf, sizeof(char), sizeof(char)*79, myfile);
    printf("%s", buf);
  }
  fclose(myfile);
}

feof检查以确保尚未到达文件末尾。 memset ,将缓冲区中的所有内容设置为 0。 fread将从文件中读取多达 79 个字符到缓冲区中。 请注意,最大大小应为 79 而不是 80,即缓冲区的大小。 这是因为数组中的最后一个位置应为 null 字符“\0”保留,该字符向 C 表明该字符串已结束。

不要使用fgets 这个 function 被认为是不安全的,因为它可能导致缓冲区溢出,其中字符写入超过为字符串分配的 memory 空间。

如果您是一般编程新手,我建议您在学习 C 之前先学习一种对初学者更友好的语言,例如 Python。 C 被认为对新程序员来说很棘手,因为它没有自动 memory 管理、面向对象的编程功能或大型标准库。

问题是您试图打印 FILE 指针而不是文件的内容 - 您需要一个变量来存储它。

看到其他方法很有趣。 这是 fscanf() 的实现 -

#include <stdio.h>
#define FILENAME "test.txt"

int main(void)
{
    FILE *myfile;
    char string[81] = {'\0'};

    myfile=fopen(FILENAME , "r");
    if(myfile == NULL)
    {
        printf("The file test.txt could not be found! Exiting...\n");
        return -1;
    }
    while(fscanf(myfile, " %80[^\n]s", string) != EOF)
    {
        printf("%s\n", string);
    }
    fclose(myfile);

    return 0;
}

当您打开文件时,如果操作失败 NULL 将被返回,最好明确检查这一点,以便您知道出了什么问题。

fscanf() 返回成功读取的次数(此处为 1,用于 1 次转换为字符串),如果已到达文件末尾,则返回 EOF。 格式字符串首先使用空格来删除输入 stream 中的所有前面的空格(换行符、空格、制表符)。

在 scanf() 函数中使用字段宽度说明符(80)意味着只会读取这么多字符,因此输入不能 go 超过分配的空间 - 有用!

[^] 表示 stream 将被读取,直到遇到指定的字符。 [^\n] 是一种获取带有空格的字符串的方法,因为 scanf() 系列通常只读取遇到字符串的空格。 请注意,不会删除换行符(它仍然是流中的第一个)。

然后它打印字符串,并添加一个换行符。 该程序将遍历文件中的行数(最多 80 个字符,由换行符分隔)。 如果您想保留这些行,您可以将字符串设为一个 char arrays 数组并每次递增。 这是 fscanf() 格式字符串中的第一个空格派上用场的地方,它将删除仍在 stream 开头的换行符(和任何其他前面的空格)。

我还没有找到任何在线学习 C 的权威教程,但是有很多可用的。 当前的标准对初学者不友好,但可以免费获得一份草案: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf

另一个很好的资源(但不是教程)是http://c-faq.com/

我发现的标准库函数的来龙去脉的最佳参考是 Harbison & Steele 的 C:参考手册 - 但不幸的是它不是免费的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM