【问题标题】:my c++ file is not opened , why?我的 c++ 文件没有打开,为什么?
【发布时间】:2018-03-24 07:33:47
【问题描述】:
 cout<<"enter name of file : " <<endl;
    char nof[30] ;
    for (int i=0;i<20;++i){
            cin>>nof[i];
        if (nof[i-1]=='x'){
            if (nof[i]=='t'){
               break;
            }
        }
    }
    fstream file1;
    file1.open(nof);
    if (file1.is_open()) cout<<"file is open"<<endl;

这是一个代码,它应该从用户那里获取文件的名称来创建 但是我检查了它是否打开了,它没有,怎么办?

【问题讨论】:

  • 您需要提供 MCVE。您可以在网站文档中找到说明。
  • 编译所有警告和调试信息:g++ -Wall -Wextra -gGCC。阅读文档,尤其是 std::fstreamopen 可能因多种原因而失败(可能是特定于操作系统的;对于 Linux,请参阅底层 open(2) 系统调用中的错误...)。 Use the gdb debugger.
  • 您从cin 读取输入的代码非常脆弱:它可能会做一些您意想不到的事情。我建议你添加一行 `std::cout

标签: c++ file


【解决方案1】:

试试这个:

#include <string>
#include <iostream>
#include <errno.h>
#include <fstream>
#include <cstring>

using namespace std;

int main() {
    cout << "Enter the name of the file : ";
    string file_name;
    getline(cin, file_name);

    fstream file_stream;
    file_stream.open(file_name);

    if (file_stream.is_open()) {
        // File Stuffs goes here...........
        cout << "The file is open" << endl;
    } else {
        // The file may not exists or locked by some other process.
        cout << strerror(errno) << endl; // Edited this line.
    }
}

【讨论】:

  • 这不能回答 为什么 file_stream.open 失败的问题(可能是权限问题、文件丢失、资源不足等)。但它确实检测到了故障。
  • @BasileStarynkevitch 很难说为什么file_stream.open失败了,文件可能不存在或者可能被其他进程锁定了。
  • 在 Linux 和 POSIX 上,您可以在 std::fstream::open 失败后使用 errno(3) - 这将使用 open(2)- 并给出失败的原因。 AFAIK,没有标准的 C++14 方法可以得到这样的原因。
  • @BasileStarynkevitch 谢谢,我已经编辑了这些行。 errno也存在于windows中。
  • 还有其他潜在问题 - 例如,cin &gt;&gt; file_name 将跳过前导空格,开始读入 file_name,但如果它看到另一个空格字符则终止,因此无法处理任何文件名嵌入的空白。检查输入操作是否成功也是最佳实践,如if (cin &gt;&gt; file_name) { ... } else std:cerr &lt;&lt; "unable to read filename from stdin\n";if (getline(std::cin, file_name)) { ... } else ... 处理嵌入的空白。
【解决方案2】:

您处理用户输入的方式使变量nof 在您正在运行的操作系统上成为无效的文件路径。这就是 fstream::is_open() 返回 false 的原因。

for (int i=0;i<20; ++i){
  cin >> nof[i];
  if (nof[i-1]=='x'){
    if (nof[i]=='t'){
      break;
    }
  }
}

此代码接受用户输入,直到获得xt。但在 C/C++ 中,char*char[] 类型的有效字符串必须以 \0 字符结尾。因此,如果您仍然喜欢处理输入的方式,请在中断循环之前将 \0 附加到 nof 的末尾。

for (int i=0;i<20; ++i){
  cin>>nof[i];
  if (nof[i-1]=='x'){
    if (nof[i]=='t'){
      nof[i+1]=0; //or nof[i+1]='\0' or nof[i+1]=NULL;
      break;
    }
  }
}

但我建议你改用std::stringgetline,上面的方式比较尴尬。

std::string nof;
std::getline(std::cin, nof);

std::fstream file;
file.open(nof.c_str(), std::fstream::in | std::fstream::out);

【讨论】:

  • std::string nof; std::getline(std::cin, nof);我一开始就试过了,但它没有用,并且一直给我错误,因为 file.open(//takes char only)
  • @MohamedAbdelhamid 使用 file.open(nof.c_str());
  • cout
  • getline(cin, nof) 之前尝试cin.ingore(INT_MAX)。看来您的输入缓冲区已经有一行了。
  • 完整代码为:std::string nof;std::cin.ignore(INT_MAX);std::getline(std::cin, nof);std::fstream file;file.open(nof.c_str());
【解决方案3】:

Mohit's answer 告诉您如何检测std::fstream::open 的故障。

该函数通常会使用一些操作系统服务来打开文件,通常是一些open system call,例如 Linux 上的open(2)(可能由于多种原因而失败)。

您的程序有问题,因为您的nof 可能不包含有效的文件路径。我建议在阅读之前使用memset(nof, 0, sizeof(nof)) 清除它,并使用您的调试器,例如gdb 找到你的错误(如果你输入的文件名只有三个字符,或者四十个字母之一,你的程序将无法运行)

您可以向您的操作系统询问失败的原因。在 Linux 上,您将使用 errno(3)(例如,通过 perror(3))。

据我所知,C++标准并没有规定如何查询std::fstream::open失败的原因(并且可能不需要fstreamerrno之间的关系)

迂腐地,C++ 标准并不要求std::fstream 使用操作系统文件。当然,在实践中,fstream-s 总是使用它们。但原则上,您可能会在没有文件甚至没有操作系统的情况下使用 C++14 实现(但我不能说出任何名称)。

文件的概念在实践中与operating systemsfile systems 紧密相关。您可以拥有没有文件的操作系统(过去,OS/400PalmOS、GrassHopper 和其他学术操作系统),即使这在今天是非常不寻常的。

文件的概念特定于操作系统:Windows 上的文件与Unixz/OS 上的文件不同。

语言标准规范(如 C++11 n3337、C11 n1570、Scheme R5RS)是用英文编写的,它们故意对“文件”或“文件流”含糊其辞(正是因为不同的操作系统有不同的概念)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多