【问题标题】:Read .txt file in .c file for iOS在 iOS 的 .c 文件中读取 .txt 文件
【发布时间】:2017-01-24 18:59:30
【问题描述】:

背景

我正在开发一个应用程序,该应用程序调用我公司以前用(普通)C 编写的库。我的应用程序的主要部分是用 Obj-C 编写的。在 C 代码中的某一时刻,库需要打开并从 .txt 文件中读取数据。 .txt 文件将由应用程序主体中的 Obj-C 创建。


问题

我无法通过 C 代码找到 .txt 文件。具体来说,当我尝试fopen 文件并将其分配给FILE 变量时,该变量始终为NULL。现在,该文件正在写入我的应用程序的 Documents 文件夹(但如果这是问题,那么我可以更改它)。我已启用文件共享,因此我能够通过 iTunes 验证文件是否正确写入并存在于 Documents 文件夹中。


我的尝试

这是我目前尝试过的一些代码。

应用内:

NSURL *docs = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
const char *dir = [docs UTF8String];
myLibraryEntryPoint(dir,(int)[docs length]);

在图书馆:

char *new_str;
if ((new_str = malloc(strlen(directory)+strlen("/myFile.txt")+1)) != NULL)
{
    new_str[0] = '\0';
    strcat(new_str,directory);
    strcat(new_str,"/myFile.txt");
}
else
{
    fprintf(stderr, "malloc failed!");
}
FILE *fp=fopen(new_str, "r");

我还在库中尝试了以下内容:

FILE *fp=fopen("Documents/myFile.txt", "r");
FILE *fp=fopen("/Documents/myFile.txt", "r");
FILE *fp=fopen("myFile.txt", "r");
FILE *fp=fopen("/myFile.txt", "r");
FILE *fp=fopen("Documents\myFile.txt", "r");
FILE *fp=fopen("Documents\\myFile.txt", "r");
FILE *fp=fopen("\Documents\myFile.txt", "r");
FILE *fp=fopen("\\Documents\\myFile.txt", "r");

正如我上面所说,在每次尝试之后,fp 始终是NULL在 iOS 环境中打开文件的正确 c 语法是什么? 我没有对我的项目的构建设置进行任何更改以更改工作目录,如 in@987654322 所述@of thesequestions,因为与这些问题不同,我的应用程序自己创建了 .txt 文件。


分辨率

原来文件路径区分大小写。我的图书馆正在寻找myFile.TXT,我的应用程序正在那里写信给myFile.txt。 FML。

我将把这个问题留在这里,因为我认为 cmets 中有一些很好的信息以及有关文件路径语法以及库如何处理当前目录的建议答案。这些信息将来可能对其他人有用。

【问题讨论】:

  • 由于您正在处理相对路径,您可以尝试打印当前目录吗? puts(getcwd());IIRC。
  • 不要试错,而是使用调试器并使用文件的绝对路径。 /myFile.txt 是绝对路径,但很可能不是文件所在的路径!并提供minimal reproducible example
  • @Jean-FrançoisFabre:我应该把puts(getcwd()); 放在我的C 代码库中,对吧?如果我只是键入该行,它会引发编译器错误 - getcwd 部分不会显示在自动完成中,所以我想知道是否不支持?
  • 尝试使用包含行:#include <unistd.h> char *getcwd(char *buf, size_t size); 但可能不支持。
  • @GeneralMike:是的,您的进程似乎以根目录作为当前目录开始。您必须 chdir 到您的应用程序目录或提供它的完整绝对路径。

标签: ios objective-c c io


【解决方案1】:

Documentsdirectory 的路径在 Objective-C 中可以这样访问:

NSString *documentsPath = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES)[0];

在 C 中使用这样的 NSString 路径时,您必须将 NSString 转换为 UTF8 字符串:

NSString *fullPath = [documentPath stringByAppendingPathComponent:@"myFile.txt"];
File *f = fopen(fullPath.UTF8String, "r");

请注意fopen() C 函数需要传递所需文件的绝对路径才能打开它。

如果 fopen() 返回 NULL,您可以通过检查 errno 的错误号和 strerror() 函数(来自 )来检查问题所在,以获得人类可读的解释:

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

File *fileHandler = fopen( fullPathToFileAsUTF8String, openMode );
if( fileHandler == NULL ) {
    fprintf(stderr, "File open error: %s\n", strerror(errno));
}

【讨论】:

  • 这与我在My Attempts 下列出的第一部分中所做的不一样吗?该库是一个 .c 文件,这意味着我不能在该文件中包含任何 obj-c 代码。
  • C字串与UT8字串不同。
  • 我正在使用UTF8String。我尝试使用NSSearchPathForDirectoriesInDomains,看起来并没有改变任何东西。
  • 所以,您的应用程序创建的文件可能没有关闭。尝试使用 iTunes 文件共享打开您手动创建的文件。
  • 这是个好主意。我复制了该文件,在名称的末尾添加了一个2,然后用iTunes 将其放回,并更改了库中的代码以查找2 文件,但仍然没有找到它。
【解决方案2】:

我认为您第一次尝试的问题是您将 URL 传递给需要路径的库函数。试试:

NSURL *docs = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSString *docsPath = docs.path;
const char *dir = [docsPath UTF8String];
myLibraryEntryPoint(dir,(int)[docsPath length]);

【讨论】:

    【解决方案3】:

    遇到了类似的问题。我有一个 C 语言库,我需要从中读写文件。

    我编写了下面的代码来查找应用程序的 Documents 文件夹的路径:

    char path[256] = {0};
    strcpy(path, getenv("HOME"));
    strcpy(path, "/Documents/file.txt");
    FILE *file = fopen(path, "r");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2020-10-09
      • 2014-06-22
      • 1970-01-01
      • 2017-08-31
      相关资源
      最近更新 更多