使用FILE指针写文件时出现分段错误

4
以下是C++代码,“Segmentation fault”错误出现:
```cpp ```
```cpp ```
#include <cstdio>

int main(int, char**) {
  FILE *fp;
  fp = fopen("~/work/dog.txt", "w");
  fprintf(fp, "timer, timer3, timer5, timer6, timer7");
  fclose(fp);
}

顺便提一句,这是C代码,需要使用C++编译器进行编译,因为使用那些C API的C++开发者应该已经过时了。它们很烦人。 - Kuba hasn't forgotten Monica
@Kuba Ober:没有办法保留这些函数吗?我无法让新的函数工作。 - Luatic
你可以继续使用它们,但在C++代码中会显得很笨拙。 - Kuba hasn't forgotten Monica
3个回答

9
你的路径无效,并且永远不会起作用,因此将设置为,你会收到一个段错误。提示:shell会扩展字符“~”,因此你不能在fopen的参数中使用它。
以下是正确、安全的实现方式。这已经过测试。这也是为什么明智的人不会在没有其他方法的情况下编写C代码的原因 :)
// main.cpp
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>

int main(int, char**)
{
    const char * home = getenv("HOME");
    if (home == NULL || strlen(home) == 0 || access(home, F_OK) == -1) abort();
    const char * subPath = "/work/dog.txt";
    char * path = (char*)malloc(strlen(home) + strlen(subPath) + 1);
    if (path == NULL) abort();
    strcpy(path, home);
    strcat(path, subPath);
    FILE *fp = fopen(path, "w");
    if (fp != NULL) {
        fprintf(fp, "timer, timer3, timer5, timer6, timer7");
        fclose(fp);
    }
    free(path);
}

1
一些事情:
  • 在使用之前,你需要检查fp是否为NULL,否则当文件未找到时会导致段错误。

  • 在将路径传递给fopen之前,你需要解析完整路径(fopen不知道如何处理“〜”)

例如:

FILE *fp = NULL;
char path[MAX];
char *home = getenv ("HOME");
if ( home ) 
{
    snprintf(path, sizeof(path), "%s/work/dog.txt", home);
    // now use path in fopen
    fp = fopen(path, "w");

    if ( fp )
    {
        fprintf(fp, "timer, timer3, timer5, timer6, timer7");
        fclose(fp);
    }
    else
    {
        std::cout << "your dog is missing" << std::endl;
    }
else
{
    std::cout << "You are homeless" << std::endl;
}

0

如果您尝试打开的文件不存在,就会发生段错误。这与Qt无关。

测试“fp”的空值并正确处理错误。类似这样的操作:

FILE *fp = fopen("/path/to/work/dog.txt", "w");
if (fp == NULL)
{
    printf("File does not exist.\n");
    // throw exception or whatever.
}

请参考Kube Ober的答案。 - Mankalas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接