【问题标题】:A very odd issue with std::fclose()std::fclose() 的一个非常奇怪的问题
【发布时间】:2016-08-16 11:19:33
【问题描述】:

我正在使用 MS Visual Studio 对文件进行一些简单的读/写操作。这是我编写的代码的简化版本:

#include <cstdio>
#include <cstring>

void write_into_file(const char* filename);

int main()
{
    write_into_file("settings.ini");
    write_into_file("com4.ini");
    return 0;
}

void write_into_file(const char* filename)
{
    FILE* f = std::fopen(filename, "wb");
    const char* text = "Some text I want to write...";
    std::fwrite(text, 1, strlen(text), f);
    std::fclose(f);
}

每当我运行程序时,它都会卡住并且不会结束。我调试了代码并追踪到它。事实证明,除了包含fclose 的行之外,代码的所有部分都可以正常运行并且没有任何问题。我的意思是,调试器在到达该行时会卡住。为什么会发生这种情况,问题是什么?

编辑: 我怀疑问题出在文件名上,特别是com4.ini。于是我把代码改成如下:

#include <fstream>
#include <sys/stat.h>

void write_into_file(const char* filename)
{
    std::ofstream fp(filename, std::ios::out);
    if (fp.is_open())
        fp.close();
    struct stat info;
    if (stat(filename, &info) != 0)
    {
        perror("An error occurred. Write permissions maybe?!!");
        return;
    }
    FILE* f = std::fopen(filename, "wb");
    const char* text = "Some text I want to write...";
    std::fwrite(text, 1, strlen(text), f);
    std::fclose(f);
}

有趣的是,它成功地写入了第一个文件。对于第二个文件,它通过了存在性检查,然后再次卡在最后一行。它甚至不会抛出异常!只是呆在那里无所事事......

【问题讨论】:

  • 这对我来说似乎是一个权限或访问问题(但我只是推测)。您可以手动创建文件吗? (如果是权限问题,您将无法这样做)。此外,如果您在 std::fclose 之前添加一个 std::fflush 调用,您的应用程序将被卡在 fflush 调用中。如果是这种情况,解决方案将是 (1) 在操作系统级别修复权限或 (2) 在您的应用程序中显式设置当前工作目录或 (3) 显式设置文件的路径到您具有写入权限的位置.
  • 与这个问题无关,但你必须使用std::strlen而不是strlen
  • ... 或更改为 std::string 并使用它的大小
  • 请看问题的编辑部分
  • msdn.microsoft.com/en-us/library/windows/desktop/… CON、PRN、AUX、NUL、COM1、COM2、COM3、COM4、COM5、COM6、COM7、COM8、COM9、LPT1、LPT2、LPT3、LPT4、LPT5、LPT6、LPT7 、LPT8 和 LPT9。还要避免这些名称后跟扩展名;例如,不推荐使用 NUL.txt。有关详细信息,请参阅命名空间。

标签: c++ file


【解决方案1】:

您不能使用 COM4.ini 作为文件名,请参阅https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx 特别是

"CON、PRN、AUX、NUL、COM1、COM2、COM3、COM4、COM5、COM6、COM7、COM8、COM9、LPT1、LPT2、LPT3、LPT4、LPT5、LPT6、LPT7、LPT8 和 LPT9。还有避免这些名称后跟扩展名;例如,不推荐使用 NUL.txt。有关详细信息,请参阅命名空间。"

它尝试打开一个名为 COM4 的串行端口...

【讨论】:

  • 那么我怎样才能在不卡住的情况下检查这些名称呢?
  • @polfosol 可能最简单的方法是将名称部分(在点之前和最后一个目录分隔符或驱动器号之后,如果有的话)与给定的保留名称列表进行比较。
  • 另外,您可以允许保留的文件名,因为它们无论如何都是有效的文件名。如果您指定“com4.ini”,系统会假定您确实是说的话,即您要写入 COM 端口。在某些情况下,这是一件有效的事情。在你的情况下,它不是,所以不要这样命名它,而不必编写一个“nanny”函数来阻止你这样做。
猜你喜欢
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 2021-08-26
  • 2011-07-12
  • 1970-01-01
  • 2013-02-07
  • 1970-01-01
  • 2012-06-17
相关资源
最近更新 更多