【问题标题】:C++ open() fails for no apparent reason [closed]C ++ open()无缘无故失败[关闭]
【发布时间】:2010-04-14 15:56:56
【问题描述】:

以下代码:

char filename[64];
ifstream input;

cout << "Please enter the filename: " << endl;
cin >> filename;

input.open(filename);

if (!input.is_open())
{
    cout << "Opening file " << filename << " failed." << endl;
    exit(1);
}

失败,它进入 if() 并退出。这可能是什么原因?我正在使用 Microsoft Visual C++。当我将文件名硬编码为常量时,结果却是乱码:

http://pici.se/pictures/CNQEnwhgo.png

建议?

[编辑]

我设法将它浓缩成这个失败的最小测试用例:

#include <iostream>
#include <fstream>

using namespace std;

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

    ifstream input;

    input.open("C:\\test.txt");

    if (!input.is_open())
    {
        cout << "Failed." << endl;
        exit(1);
    }

return 0;
}

我想知道键盘映射是否可能存在一些差异?我在某些字符集中输入文件名,而文件系统以其他名称知道它?顺便说一句,我使用的是 Windows。

[编辑]感谢您的所有帮助,但我现在放弃了。我将使用 C 风格的 fopen 代替。 :)

[编辑] 天哪。现在觉得自己好傻。原来该文件实际上被命名为 test.txt.txt 并且 Windows 隐藏了第二个 .txt 再次感谢您的所有帮助...

【问题讨论】:

  • 什么结果出现了乱码,又是如何产生的?显然发生的是文件没有打开,并且有很多可能的原因。例如,您确定该文件存在吗?
  • 字符文件名[64]; operator>>。
  • 你打算打开这个输出,不是吗?您没有在.open() 中指定打开模式,默认为out
  • 它最终出现乱码,因为您打印了未初始化变量 filnamn 的内容(在屏幕截图中)。
  • 存在的实际文件名与您尝试打开的文件名的大小写完全相同(包括扩展名)?也许尝试先打开一个 ofstream 来创建文件,看看它是否会创建你认为应该的文件,然后打开它进行阅读。

标签: c++ file input


【解决方案1】:

我建议从您的故障代码中打印errno(包括cerrno.h),或调用perror()(包括cstdio.h)。归根结底,C++ 方法调用的是 C stdlib 函数,因此即使您没有遇到异常,也应该找到错误代码。

【讨论】:

  • perror() 声明没有这样的文件或目录。这不应该是真的。
  • @jondoe - perror() 是正确的。现在你必须做更多的挖掘来找出为什么它认为文件不存在。至少您知道这不是权限问题,也不是 open() 失败的十几个其他可能原因之一。接下来我建议创建用于写入的文件,看看它实际上在哪里结束。
  • @jondoe - 你不是在 Cygwin 下编译,是吗?因为如果你是,你需要使用 Unix 风格的路径名,而不是 Windows 风格的。
  • 不。我正在使用 Microsoft Visual C++ 6.0。我将只使用 C 风格的 fopen 代替。
【解决方案2】:

你能确定文件名是你认为的那样吗?

cin >> filename; 
cout << filename; 

ifstream myFile(filename); 
if ( myFile.is_open() ) { 
   // ... 
}

在 Unix/Linux 系统上,请记住文件名区分大小写。

ThisIsMyFile 
thisIsMyFile 

是两个不同且独立的文件。

[编辑]

ifstream::open 定义为:

void open ( const char * filename, ios_base::openmode mode = ios_base::in );

打开一个名为 s 的文件,将其内容与流对象相关联以对其执行输入/输出操作。允许的操作和一些操作细节取决于参数模式。

函数有效调用rdbuf()->open(filename,mode)。

如果对象已经有关联的文件(打开),则函数失败。

失败时,设置失败位标志(可以通过成员失败检查),并且根据设置的值设置异常,可能会引发异常。


尝试将“C:\test.txt”更改为简单的“test.txt”并从“C:\”目录运行此程序。

Here is an exact similar sample:

// ifstream::is_open
#include <iostream>
#include <fstream>
using namespace std;

int main () {

  ifstream infile;
  infile.open ("test.txt");
  if (infile.is_open())
  {
    while (infile.good())
      cout << (char) infile.get();
    infile.close();
  }
  else
  {
    cout << "Error opening file";
  }
  return 0;
}

如果这个明显的东西不起作用,是时候启动调试器了。

【讨论】:

  • 斜杠也可能存在问题:/ 正斜杠不是普遍接受的。可能是提问者从键盘输入双斜杠\\
  • 我确定文件名是正确的。我正在使用 Windows。我用一个失败的小代码更新了我的原始帖子。
  • 仍然不适用于该代码。我想我会改用 C 风格的 fopen,或者安装一个新的 IDE+编译器。
  • @jondoe:你用的是什么编译器?
  • @Chris Kaminski,我使用的是 Microsoft Visual C++ 6.0。
【解决方案3】:

该文件名应该是C:\\test.txt 还是C:\test.txt?反斜杠是 C 和 C++ 等语言中的转义字符,在输入中需要两个反斜杠才能得到一个。换句话说,您可能想要C:\\\\test.txt,或者C://test.txt 可能会起作用(对于许多Windows 文件处理,正斜杠的作用类似于反斜杠)。

编辑:反斜杠没有按我的意图出现,因为这里的格式化代码显然具有相同的转义约定。我通过用反引号引用来改变这一点,就好像字符串是代码一样。

【讨论】:

  • 我正在使用双斜杠。我已经尝试过向前和向后。
  • 呃。我进行了编辑以使反斜杠正确显示。
  • 除了 URL 之外,您不能在任何地方使用双斜杠。
【解决方案4】:

当前用户是否有打开文件的权限?

【讨论】:

  • 其他进程可以锁定文件吗?编辑?僵尸进程?
猜你喜欢
  • 2019-02-01
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-17
  • 1970-01-01
相关资源
最近更新 更多