为啥将字符串作为文件名而不是 char* 传递时出现错误?

Posted

技术标签:

【中文标题】为啥将字符串作为文件名而不是 char* 传递时出现错误?【英文标题】:Why do I get an error when passing a string as a filename, but not a char*?为什么将字符串作为文件名而不是 char* 传递时出现错误? 【发布时间】:2014-11-03 15:15:47 【问题描述】:

我了解 char 指针用于在 C 中创建字符串(带有空终止符)。但我不明白为什么在 C++ 中将字符串作为文件名传递时会出错,但它适用于 char*

h 原型和 cpp 函数签名在这两种情况下都匹配。

我已经包含了一些代码摘录以及我对这个“实用程序”文件的所有包含(除了读取和写入功能之外,我还有一些其他功能。

//from the header includes

#include <string>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <limits>
#include <cctype>
#include <cstdlib>



//from the cpp file


//this one throws and error!
void readFiles(string fileName1)


    ifstream file1;
    file1.open(fileName1);

    //to do implement read...



//This one works
void readFiles(char* fileName1)


    ifstream file1;
    file1.open(fileName1);
    //to do implement read...


我得到的错误是:

std::basic_ofstream::open(std::string&)没有匹配函数

我也尝试过通过引用和指向字符串的指针传递。 这是因为文件名仅作为 char 数组读取,有些挂在 C 中吗?

【问题讨论】:

你需要 C++11 来处理这个重载。见en.cppreference.com/w/cpp/io/basic_ifstream/open。 或者你可以使用fileName1.c_str() 在前现代 C++(C++03 及之前)中,std::fstream 的构造函数采用 const char *,而不是 std::stringstring 版本在 C++11 及更高版本中可用。 课程落后是很正常的。教科书、讲座、作业等的更新需要时间;发布完全兼容的工具;并将这些工具推广到实验室工作站。 【参考方案1】:

这是 ifstream 上 open 的签名:-

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

所以,传递字符串是行不通的。

你可以的

std::string str("xyz.txt");
readFile( str.c_str() )

但是,在 C++11 中有两个重载:-

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

如果你使用过 C++11,就会少一篇关于堆栈溢出的帖子...

【讨论】:

以上是关于为啥将字符串作为文件名而不是 char* 传递时出现错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在将命令行图像文件中的参数作为参数传递时出现错误

为啥 putchar、toupper、tolow 等采用 int 而不是 char?

为啥关键字参数必须作为带有符号键的哈希传递,而不是 Ruby 中的字符串键?

为啥我们不能将字符串作为模板参数传递?

将字符串从 std::string 转换为 const char * 时出现数据丢失问题

为啥将 Array.from 作为回调传递给 Array.flatMap 时出现 TypeError: 0 is not a function?