无法打开一个文本文件在C中,我想要将文本作为数据读取并写入数组中。

huangapple go评论126阅读模式
英文:

Can't open a text file in C from which i want to read text as data and write it into an array

问题

#include <stdio.h>

int main(void){

    FILE *ptr;
    ptr = fopen("example.txt", "r");
    if (ptr == NULL){
        printf("File not opened or found");
        return 1;
    }
    
    char str[20];
    fgets(str, sizeof(str), ptr);
    printf("Read text from example.txt is: %s\n", str);

    return 0;
}
英文:
#include &lt;stdio.h&gt;

int main(void){

    FILE *ptr;
    ptr = fopen(&quot;example.txt&quot;, &quot;r&quot;);
    if (ptr == NULL){
        printf(&quot;File not opened or found&quot;);
        return 1;
    }
    
    char str[20];
    fgets(str, sizeof(str), ptr);
    printf(&quot;Read text from example.txt is: %s\n&quot;, str);

    return 0;
}

I'm new to C and i got quite a lot confused about the basic file access logic in C, my first question is why did fgets() function accept ptr instead of *ptr as the third argument? Why the address of the FILE struct instead of what it references to?
When I run the code i always get the error in the if's body, I'm running a windows machine and can't get my C code to retrieve example.txt using fopen() function. Any help would be appreciated.

答案1

得分: 3

所有的stdio函数都接收一个指向FILE结构的指针,以便能够修改结构的内容。如果你传递了FILE结构本身,它们将会接收到它的一个副本,因为C通过值传递参数(除了数组,在作为函数参数时会自动转换为指针),它们所做的任何更改都不会持久保存。这使得FILE结构能够保持打开流的状态。

如果fopen()不起作用,可能是因为文件不在正确的文件夹中。相对路径名是基于你的工作目录进行解释的,而不是包含程序的目录。

英文:

All the stdio functions receive a pointer to the FILE struct so they can modify the contents of the structure. If you passed the FILE struct itself, they would receive a copy of it, because C passes arguments by value (except for arrays, which are automatically converted to a pointer when used as a function argument), and any changes they made would not persist. This allows the FILE struct to keep the state of the open stream.

If fopen() isn't working, it's probably because the file is not in the correct folder. Relative pathnames are interpreted based on your working directory, not the directory containing the program.

答案2

得分: 2

以下是您要求的代码部分的翻译:

标准流处理文件等的函数,声明在 `<stdio.h>` 中,使用由库分配的不透明 `FILE` 结构的指针。 实现的详细信息对库保密,程序所需的仅是由 `fopen()`  `freopen()` 返回的 `FILE` 指针,并作为参数传递给输入和输出函数。

库函数适当地更新 `FILE` 结构以实现缓冲方案和其他翻译功能。 如果直接传递了 `FILE` 结构,它将无法更新,因为在 C 中结构是按值传递的,所以库函数只会接收结构的副本,任何更新将在函数返回时丢失。

这种方法非常通用,许多编程语言在幕后都使用它。 Java 对象通常作为指针传递给方法。 JavaScript 对象和数组也是如此。  C++ 中接收对象引用的函数基本上得到了永远不会为 null 的指针。 在这些情况下,通过 `.` 运算符访问对象属性会被翻译为指针解引用,可能会有一些或没有额外的运行时检查和查找。

在您的示例中,您说文件无法打开:产生更详细的错误消息是一个好习惯,可以帮助跟踪此类失败。文件无法打开可能是因为运行时当前目录中没有该文件。

您还应该检查 `fgets()` 可能的失败,并使用 `fclose()` 关闭流。
#include <errno.h>
#include <stdio.h>
#include <string.h>

int main(void) {
    FILE *ptr = fopen("example.txt", "r");
    if (ptr == NULL) {
        fprintf(stderr, "无法打开 example.txt: %s\n", strerror(errno));
        return 1;
    }
    
    char str[100];
    if (fgets(str, sizeof(str), ptr)) {
        printf("从 example.txt 读取的文本是:%s\n", str);
    } else {
        printf("无法从 example.txt 读取:%s\n", 
               ferror(ptr) ? "读取错误" : "空文件");
    }
    fclose(ptr);
    return 0;
}
英文:

The standard stream function to handle files and such, declared in &lt;stdio.h&gt; use pointers to opaque FILE structures allocated by the library. The details of the implementation are kept private to the library, all the program needs are FILE pointers returned by fopen() or freopen() and passed as argument to input and output functions.

The library functions update the FILE structure appropriately to implement the buffering scheme and other translation functionalities. If the FILE structure was passed directly, it could not be updated as structures are passed by value in C so the library function would just receive a copy of the structure and any updates would be lost as soon as the function returns.

This method is very general and is used by many programming languages behind the scenes. Java objects are typically passed as pointers to methods. The same for javascript objects and arrays. Functions receiving object references in C++ basically get pointers that are guaranteed to never be null. In these circumstances, object property access via the . operator are translated as pointer dereferencing with some or no additional runtime checks and lookups.

In your exmaple, you say the file cannot be opened: producing a more informative error message is a good habit to help track such failures. The file cannot be open probably because it is not present in the current directory at run time.

You should also check for potential failure in fgets() and close the stream with fclose().

#include &lt;errno.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

int main(void) {
    FILE *ptr = fopen(&quot;example.txt&quot;, &quot;r&quot;);
    if (ptr == NULL) {
        fprintf(stderr, &quot;Cannot open example.txt: %s\n&quot;, strerror(errno));
        return 1;
    }
    
    char str[100];
    if (fgets(str, sizeof(str), ptr)) {
        printf(&quot;Read text from example.txt is: %s\n&quot;, str);
    } else {
        printf(&quot;Cannot read from example.txt: %s\n&quot;, 
               ferror(ptr) ? &quot;read error&quot; : &quot;empty file&quot;);
    }
    fclose(ptr);
    return 0;
}

huangapple
  • 本文由 发表于 2023年8月11日 01:29:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76878050.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定