另一个关于初学者在C中打开的问题

时间:2011-06-12 18:15:17

标签: c printf fopen

我是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语言规范的网站,可能包括如何使用库函数的示例。

非常感谢你的时间。

安德鲁

卡内基梅隆大学

5 个答案:

答案 0 :(得分:4)

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

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

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

如果要将整个文件读入缓冲区,则需要稍微多一点,因为您必须确定文件的长度,然后在正确大小的堆上动态分配内存以保存文件。 the fread page at cplusplus.com上有一个很好的教程。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

这是最安全的方法。

#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,即缓冲区的大小。这是因为数组中的最后一个点应保留为空字符'\ 0',这表示字符串已结束。

请勿使用fgets。此函数被认为是不安全的,因为它可能导致缓冲区溢出,其中字符被写入超过为字符串分配的内存空间。

如果你是一般的编程新手,我建议在学习之前学习一种比较适合初学者的语言,比如Python。对于新程序员来说C被认为是棘手的,因为它没有自动内存管理,面向对象的编程功能,或大型标准库。

答案 4 :(得分:0)

问题是您正在尝试打印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。格式字符串首先使用空格来删除输入流中的任何和所有前面的空格(换行符,空格,制表符)。

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

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

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

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

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

我发现的标准库函数的来龙去脉的最佳参考是Harbison&amp;斯蒂尔的C:参考手册 - 但遗憾的是它不是免费的。