参考知乎用户
孔乙己
的
回答
:
举一个简单的例子:我们原来的代码一直没问题,但如果要使用C++17标准就报一个错,这个错影响还挺多的。具体原因是,C++17添加了一种新类似 std::byte,而Windows头文件里自带一种类型byte。这两种类型本身并不冲突,因为一个是 std::byte,另一个是byte。但是,如果代码里广泛使用了using namspace std;再遇到byte的时候,编译器就不知道它是Windows的byte还是std:byte省略了std。所以,尽量少在工程里包含这种"大杀器"。你如果想省事,可以在自己的.cpp文件里使用(.cpp不暴露声明)。实在想在.h里用(为省事),尽量使用诸如 using std::vector;之类的,用哪个暴露哪个,而不是一次性全部暴露。
作者:孔乙己
链接:
www.zhihu.com/question/26…
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
因此,
不要用 using namespace std;
,
尤其不要在头文件中使用
,
可以用
using std::string; using std::vector;
这种
。
fstream 读文件基本用法
C 语言的舒适区和风险
之前在工作中要读写文件经常用
fopen() fwrite() fclose()
,习惯了,就不想去接触其他方法了。
但是,最近在工作中发现一些 C 方法其实很危险,不如 C++ 方法安全,例如
【C++】尽量使用 snprintf 而非 sprintf 来保证内存安全,防止类实例的私有成员变量被改写
,这篇文章中提到的 sprintf 带来的内存风险。当然, snprintf 还是 C 方法,所以,那篇文章应该还有后续,用更 C++ 的方法来实现功能。
读写文件也一样,如果
FILE * fin = fopen("xxx/xxx/xx")
失败了,而我们又没有去判断
fin == nullptr
,则将在
fwrite
时出现段错误。如果是
fread
,
memset
等,则更容易导致由于内存大小计算错误(导致申请的内存空间和操作的内存空间大小不一致),导致内存操作溢出,可能不会在此时此刻出现崩溃,而是出现在莫名其妙的地方。这给代码调试带来了更大的挑战。
因此,走出舒适区,拥抱变化,学习更多,发展,才是硬道理。
fstream 的基本用法
打开文件:
#include <fstream>
#include <string>
#include <iostream>
using std::ifstream;
using std::cout;
using std::string;
using std::endl;
void openfile(string filename) {
ifstream infile(filenmae, std::ios_base::in | std::ios_base::binary);
ifstream infile2;
infile2.open(filename, std::ios_base::in | std::ios_base::binary);
if (!infile.is_open()) {
cout << "File open failed." << endl;
除了使用 std::ifstream::is_open()
来判断文件是否打开之外,还可以通过 std::ios::
命名空间下的一些方法来判断文件的读取是否正常,具体可参考下图:
ifstream
类读文件有两大接口 get()
以及 read()
,每个接口又有多种重载函数。哦,还有个 getline()
。
实际上,因为 ifstream
类继承自 istream
类,因此,继承了来自 istream
类的相关方法:gcount
get
getline
ignore
read
tellg
seekg
等。因此,读文件的过程,其实就是调用这些方法的过程。
这里有一点需要注意一下,使用 get(char* s, streamsize n)
方法时,会读取前 n - 1 个字符,并在第 n 个字符添加 "\0"。因此,需要使用 get
读取4个文件中的字符时,实际上需要申请 char buf[5]
,并调用 infile.get(buf, 5)
。
所以,如果是按字节流读 4 个字节的数据时,更不容易引起歧义的读取建议使用 infile.read(buf, 4)
。