【问题标题】:Help with opening a file in C on Xcode帮助在 Xcode 上用 C 语言打开文件
【发布时间】:2010-01-13 06:23:41
【问题描述】:

我正在尝试在 C 中打开一个名为 test 的简单 .rtf 文件。我正在使用 Xcode。我的代码是:

#include <stdio.h>
#include <stdlib.h>

int main (int argc, const char * argv[]) {

    FILE *filePtr;
    filePtr = fopen("test.rtf", "r");
    if (filePtr == NULL) {
        fprintf(stderr, "Can't open \"test\"\n");
        exit(EXIT_FAILURE);
    }
    else {
        printf("File open successful\n");
        int x;
        /* read one character at a time until EOF is reached */
        while ((x = fgetc(filePtr)) != EOF) {
            printf("%c", x);
        }
    }
    fclose(filePtr);
    return 0;   
}

我的 test.rtf 文件与我的 Xcode.proj 目录位于同一目录中。我的输出是“文件打开成功”,但是我没有从文件中读取任何内容。我这样做对吗?谢谢。

【问题讨论】:

  • 如果在return 0; 之前添加putc('\n', filePtr);,你看到了什么吗?如果文件中没有换行符,您可能看不到任何内容。
  • 不,当我在返回 0 之前添加它时,我什么也看不到;
  • 嗯。命令行中的xxd -l 32 test.rtf 说什么?

标签: c xcode file


【解决方案1】:

这段代码没有任何问题。我用一个文件测试了它(虽然不是在 Xcode 中),结果是:

pax> echo hello >test.rtf
pax> ./qq.exe
File open successful
hello

所以很明显的问题是当你检查 test.rtf 时会发生什么?它实际上有任何内容吗?因为,当我这样做时:

pax> rm test.rtf ; touch test.rtf
pax> ./qq.exe
File open successful

我得到了与你观察到的相同的行为。

还可以尝试暂时将其重命名为 test2.rtf 并确保您收到错误消息。可能打开的文件副本与您想象的不同(这在 Visual C 中经常发生,因为程序运行所在的目录并不总是开发人员最初的想法)。

【讨论】:

  • 我将 filePtr = fopen("test.rtf", "r") 中的 "test.rtf" 更改为 "t.rtf" 以确保在文件没有打印时打印错误打开。我拥有的 .rtf 文件我只是在其中放了一些随机文本,例如“你好(换行符)这样做(换行符)工作”。
  • 我现在唯一能想到的就是测试printf()调用的返回值!
  • 更改 'printf("%c", x);' 时会发生什么到'fprintf(stderr,"%x\n", x);'?如果您在文件不存在时得到了正确的错误,请尽量减少输出调用之间的差异 - 两者都使用 stderr,都使用换行符输出。
  • 相同的输出。文件打开成功。
【解决方案2】:

看起来不错。

至于输出不足,有两种可能:

  • 您确定文件有内容吗?也许ls -l test.rtfdir test.rft
  • 可能它有一些控制字符导致写入它的终端抑制输出。

【讨论】:

    【解决方案3】:

    尝试将test.rtf 移动到您的构建目录。如果您的项目名为MyProject,请将其移至MyProject/build/Debug/

    【讨论】:

    • 不太可能是原因。 OP 说出现了File open successful
    【解决方案4】:

    我能想到两件事会导致这个问题。调用 fgetc 时出现错误,或者您获得了无法识别的输出。

    fgetc() 将在到达文件末尾或发生错误时返回 EOF。要确定这是否是错误,请在您的 while 循环之后尝试:

    if (ferror(filePtr) != 0) printf("error: %d.\n", errno);

    .rtf 文件不是纯文本文件。它可能包含一堆格式信息。你期待看到“你好……”。但你实际看到的可能是这样的:

    {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf250 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \margl1440\margr1440\vieww9000\viewh8400\viewkind0 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040 \f0\fs24 \cf0 你好。 . .

    您只是假设这是 GDB 输出,而不是您的程序的输出。

    【讨论】:

    • 什么是 GDB?因此,我尝试创建一个新的 .txt 文件,即使该文件与旧的 .rtf 文件位于同一位置,我仍不断收到“无法打开测试”。我尝试了几个不同的名称,并将文件放在调试文件夹中,并在与我的 Xcode.proj 相同的文件夹中尝试,但这似乎也不起作用。还有什么可以尝试的吗?谢谢。
    • GDB 是 GNU 调试器。 Xcode 在运行程序的调试版本时使用 GDB。您在 Xcode 控制台中看到的大部分输出都是 GDB 输出。您是否在代码中将文件名更改为 test.txt(或您命名的 .txt 文件)?
    • 是的。我创建了一个新的文本 (.txt) 文件,但由于某种原因它无法打开我的文件,并且会继续输出“无法打开文件”。
    • 下一步是找出无法打开文件的原因。 fopen 应该在错误时设置 errno,因此输出 errno。更改行 'fprintf(stderr, "Can't open \"test\"\n");' to 'fprintf(stderr, "Can't open \"test\": %d.\n", errno);'。然后查看错误编号的含义,找出需要修复的内容。顺便说一句,errno.h必须包含才能使用errno。
    【解决方案5】:

    根据您最近的 cmets,我认为您在运行程序的目录中有一个空文件 test.rtf,而您真正的 test.rtf 文件在其他目录中。也许您的 fopen() 呼叫在某个时候是 fopen("test.rtf", "w"); 而不是 fopen("test.rtf", "r");,您后来修改了它。

    要查看您的程序运行所在的目录,请将以下内容添加到您的程序中 FILE *filePtr; 行之后:

    char pwd[512];
    if (getcwd(pwd, sizeof pwd) != -1)
        printf("In directory %s\n", pwd);
    else
        fprintf(stderr, "Need bigger buffer, change '512' above\n");
    

    然后,您可以打开一个终端,执行cd &lt;directory&gt;,然后自己测试您想要的文件是否是您的程序正在打开的文件。

    【讨论】:

      【解决方案6】:

      您可能希望此文件是纯文本,而不是富文本。富文本在文件中编码了很多格式。

      【讨论】: