【问题标题】:Writing a file to users HOME directory in C在 C 中将文件写入用户 HOME 目录
【发布时间】:2016-02-02 23:18:20
【问题描述】:

我正在尝试将 .txt 文件写入用户的 HOME 目录。

我试过了:

char str[] = "TEST";
char* file = strcat(getenv("HOME"), "/dataNumbers.txt"); //I am concatenating the user's home directory and the filename to be created.
myFile = fopen(file,"w");
fwrite(str , 1 , sizeof(str) , myFile );

但是,这不会创建文件。

【问题讨论】:

  • 1. file 变量的值是多少?它是预期的文件名吗? 2. 运行此代码的用户是否有权写入$HOME?您认为这应该是安全的假设,但您仍应仔细检查该目录的权限。
  • 如果它没有创建文件,你也不应该调用fwrite()。这里明显缺乏错误检查。您需要测试 myFile 是否为 null 并调用 perror() 或其朋友(如果发现),而不是像没有那样继续。

标签: c file file-io output


【解决方案1】:

你不能strcat() 到一个环境变量。你需要另一个缓冲区:

char file[256]; // or whatever, I think there is a #define for this, something like PATH_MAX
strcat(strcpy(file, getenv("HOME")), "/dataNumbers.txt");
myFile = fopen(file,"w");

编辑要解决以下问题之一,您应该首先确保要连接的数据不会溢出file 缓冲区,或者动态分配它 - 不要忘记之后释放它.

【讨论】:

  • 修复后,可能会因为权限问题而失败。确保您有权在用户的主目录中创建文件。
  • @LeeDanielCrocker $HOME 大概是运行所示代码的当前用户的主目录。很可能应该没有权限问题......但仔细检查可能是个好主意。
  • 如果组合超过 255 个字符,则存在风险。
  • 我应该澄清一下,这是针对学校项目的,这些预防措施可以忽略。
  • @LeeDanielCrocker getenv("HOME") 返回您自己的主目录。
【解决方案2】:

您错误地使用了strcat

 char *file;
 char *fileName = "/dataNumbers.txt";

 file = malloc(strlen(getenv("HOME") + strlen(fileName) + 1); // to account for NULL terminator
 strcpy(file, getenv("HOME"));
 strcat(file, fileName);

file 现在将包含连接的路径和文件名。

显然,这可以写得更干净。我只是想直截了当。

【讨论】:

  • 您的代码中缺少几个右括号,但 +1 以获得简单直接的答案。
  • getenv("HOME")后面应该有个右括号
【解决方案3】:

C 中的字符串与其他高级语言中的其他字符串不同;也就是说,您必须自己为它们分配所有空间。使用 c-string 函数时,您需要确保为结果字符串分配了足够的内存,方法是在堆栈上保留足够的空间(即 char 文件名 [HOPEFULLY_ENOUGH])或通过堆(malloc() 和朋友)。您不能指望getenv 返回一个有足够空间供您连接的字符串;

这是一个从头到尾的完整程序,可以完成您想做的事情(减去一些迂腐的错误检查):

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

int main(void)
{
    char *filename = "/dataNumbers.txt";
    char *writeString = "TEST";
    char *home_dir = getenv("HOME");
    char *filepath = malloc(strlen(home_dir) + strlen(filename) + 1);
    strncpy(filepath, home_dir, strlen(home_dir) + 1);
    strncat(filepath, filename, strlen(filename) + 1);
    printf("%s\n", filepath);

    FILE *myFile = fopen(filepath, "w");
    fwrite(writeString, 1, strlen(writeString), myFile);
    fclose(myFile);
    free(filepath);
    return 0;
}

strncpy 将复制字符串加上空终止符(这就是+1 的原因)。 strncat 将在 null 终止符处开始串联,并且结果串联字符串本身必须以 null 终止(因此 strncat 的第三个参数中的 +1)。

我使用 malloc 和 free 因为很难确切知道文件完整路径的长度。你可以使用一些巨大的东西(比如 char[4096]),但这似乎很浪费,不是吗? malloc() 允许您准确保留所需的内存量。不多也不少。

您还可以使用 snprintf 函数进行字符串连接。我包含这个只是为了你个人的丰富,有时有多种方法来做同样的事情很好,即使 strcpy 和 strcat 会让你的代码读者更清楚你的意图:

char *filename = "/dataNumbers.txt";
char *writeString = "TEST";
char *home_dir = getenv("HOME");
size_t size = strlen(home_dir) + strlen(filename) + 1;
char *filepath = malloc(size);
snprintf(filepath, size, "%s%s", home_dir, filename);

希望这会有所帮助!

【讨论】:

  • 别忘了释放(文件路径);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-19
  • 2022-07-13
  • 1970-01-01
  • 2014-07-10
相关资源
最近更新 更多