如何读写txt文件 C++读和写txt文件操作 查找文件中存储的字符串中逗号的位置

C++读和写文件操作说明

一、 C++读和写文件操作说明

文章目录

  • C++读和写文件操作说明
  • 一、 C++读和写文件操作说明
    • 1、打开方式
    • 2、实例代码
      • 2.1 第一版代码
      • 2.2 第二版代码
  • 二、补充部分 C++:cin、cin.getline()、getline()的用法
    • 1、cin>>
    • 2、cin.getline()
    • 3、getline()


1、打开方式

fstream头文件中,有三个主要的类分别是:

  1. fstream: 读写文件
  2. ifstream: 读文件 // input (文件数据输入到内存)
  3. ofstream: 写文件 // output (内存数据输出到文件)

每个类的对象可以调用下面几个常用的函数:

  1. open(“文件/文件路径”,打开方式)
  2. is_open() //判断这个文件是否被打开
  3. close() //关闭打开的文件

打开文件

在对文件进行读写操作之前,先要打开文件。打开文件有以下两个目的:

  • 通过指定文件名,建立起文件和文件流对象的关联,以后要对文件进行操作时,就可以通过与之关联的流对象来进行。
  • 指明文件的使用方式。使用方式有只读、只写、既读又写、在文件末尾添加数据、以文本方式使用、以二进制方式使用等多种。

打开文件可以通过以下两种方式进行:

  • 调用流对象的 open 成员函数打开文件。
  • 定义文件流对象时,通过构造函数打开文件。

总结:打开文件的方法有两种方式,一个是使用流类的构造函数打开文件,另一个采用open成员函数打开文件

  • ios::in //为输入(读)而打开文件 文件以输入方式打开(文件数据输入到内存)
  • ios::out //为输出(写)而打开文件,ofstream,默认的打开方式 文件以输出方式打开 (内存数据输出到文件)
  • ios::ate //初始位置:文件尾
  • ios::app //所有输出附加在文件末尾,用追加的方式添加
  • ios::truc //如果文件已存在则先删除文件
  • ios::binary //二进制方式

表1:文件打开模式标记

模式标记 适用对象 作用
ios::in ifstream fstream 打开文件用于读取数据。如果文件不存在,则打开出错。
ios::out ofstream fstream 打开文件用于写入数据。如果文件不存在,则新建该文件;如果文件原来就存在,则打开时清除原来的内容。
ios::app ofstream fstream 打开文件,用于在其尾部添加数据。如果文件不存在,则新建该文件。
ios::ate ifstream 打开一个已有的文件,并将文件读指针指向文件末尾(读写指 的概念后面解释)。如果文件不存在,则打开出错。
ios:: trunc ofstream 打开文件时会清空内部存储的所有数据,单独使用时与 ios::out 相同。
ios::binary ifstream ofstream fstream 以二进制方式打开文件。若不指定此模式,则以文本模式打开。
ios::in ios::out fstream 打开已存在的文件,既可读取其内容,也可向其写入数据。文件刚打开时,原有内容保持不变。如果文件不存在,则打开出错。
ios::in ios::out ofstream 打开已存在的文件,可以向其写入数据。文件刚打开时,原有内容保持不变。如果文件不存在,则打开出错。
ios::in ios::out fstream 打开文件,既可读取其内容,也可向其写入数据。如果文件本来就存在,则打开时清除原来的内容;如果文件不存在,则新建该文件。
ios::trunc fstream 打开文件,既可读取其内容,也可向其写入数据。如果文件本来就存在,则打开时清除原来的内容;如果文件不存在,则新建该文件。

注意事项:

  1. ios::binary 可以和其他模式标记组合使用,例如:
  2. ios::in | ios::binary表示用二进制模式,以读取的方式打开文件。
  3. ios::out | ios::binary表示用二进制模式,以写入的方式打开文件。

文本方式与二进制方式打开文件的区别其实非常微小。一般来说,如果处理的是文本文件,那么用文本方式打开会方便一些。但其实任何文件都可以以二进制方式打开来读写。

在流对象上执行 open 成员函数,给出文件名和打开模式,就可以打开文件。判断文件打开是否成功,可以看“对象名”这个表达式的值是否为 true,如果为 true,则表示文件打开成功。

** 网上补充版**

  • ios::in:文件以输入方式打开(文件数据输入到内存)
  • ios::out:文件以输出方式打开(内存数据输出到文件)
  • ios::app:以追加的方式打开文件
  • ios::ate:文件打开后定位到文件尾,ios:app就包含有此属性
  • ios::trunc:如果文件存在,把文件长度设为0
  • ios::binary:以二进制方式打开文件,缺省的方式是文本方式
  • ios::nocreate:不建立文件,所以文件不存在时打开失败
  • ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败

2、实例代码

2.1 第一版代码

/* 2022 08 11 */

//预备知识
//fstream  // 文件流
//ifstream  // 输入文件流 in
//ofstream  // 输出文件流 out


//ios::in:文件以输入方式打开(文件数据输入到内存)
//
//ios::out:文件以输出方式打开(内存数据输出到文件)
//
//ios::app:以追加的方式打开文件
//
//ios::ate:文件打开后定位到文件尾,ios:app就包含有此属性
//
//ios::trunc:如果文件存在,把文件长度设为0
//
//ios::binary:以二进制方式打开文件,缺省的方式是文本方式
//
//ios::nocreate:不建立文件,所以文件不存在时打开失败
//
//ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败




第一版代码

```cpp
#include
#include
#include
#include
#include
using namespace std;
void write_file()//写文件
{
	srand((unsigned int)time(NULL));

	ofstream file1;
	file1.open("car.txt", ios::app);      //   所有输出附加在文件末尾,用追加的方式写入,
	                                     //   写入追加的结果以换行的方式往下添加
		if (file1.is_open())
		{
			cout << "正确打开文件! " << endl;
			for(int i=0;i<10;i++)
			file1 << rand() % 10 << endl;

		}
	file1.close();

}


void test02()//一行一行读文件
{
	ifstream file2;
	string _str;
	file2.open("car.txt");
	if (file2.is_open())
	{
		cout << "正确打开文件! " << endl;
		//一行一行读
		if (file2.is_open())
		{
			while (getline(file2, _str))//用法:接收一个字符串,可以接收空格并输出,需包含“#include
			{
				cout << _str << endl;
			}
				

		}
	}





}

void test03()  //文件写入(不追加,覆盖原文件)
{
	//1、创建流对象
	fstream file; //可输入输出
	//2、指定打开方式
	file.open("A.txt", ios::out);
	//3、文件写入
	file << "abc256"<<" " << 123<<endl;
	file.close();


}

void test04()  //测试将字符串与数字分开输出
{
	//1、创建流对象
	fstream file; //可输入输出
	//ifstream file; //可输入
	//2、指定打开方式
	file.open("A.txt", ios::in);
	//3、文件读取(前面是字符串,后面是数字)"abc256"123
	string s;
	int num;
	if (file.is_open())
	{
		cout << "正确打开文件! " << endl;
		
			while (file >> s >> num) //文件读取至末尾
			{
				cout << s << endl << num << endl;
			}
			
	}
	
	file.close();
}


double my_atod(string tempString) //需要包含头文件 #include
{
	double result;
	stringstream ss;
	ss << tempString;
	ss >> result;
	return result;
}

void test05()
{
	//1、创建流对象
	fstream fs; //可输入输出 "123,456,789"
	//2、指定打开方式
	fs.open("stringNum.txt",ios::out);
	//3、文件写入
	fs << "123,456,789" << endl;
	fs.close();
	cout << "正确写入文件!" << endl;
}


void test06()//"123,456,789"
{
	//1、创建流对象
	fstream fs; //可输入输出
	//2、指定打开方式
	fs.open("stringNum.txt", ios::in);//ios::in:文件以输入方式打开(文件数据输入到内存)
	cout << "打开文件前! " << endl;
	//3、文件读取(前后都是数字)
	if (fs.is_open())
	{
		cout << "正确打开文件! " << endl;
		string line;//准备一个空字符串
		string::size_type position;//写成int也行
		position = 0;
		while (getline(fs,line)) //文件读取一行,并按分隔符进行处理
		{

			cout << line << endl;
		
		}
	
		cout << "从字符串的第0位开始寻找" << endl;
		//使用string::find函数的缺点:遇见','就会终止
		//if ((position = line.find('1', position)) != string::npos) //如果没找到,返回一个特别的标志c++中用npos表示,我这里npos取值是4294967295,写成-1也行,计算机中和npos相等
		//{
		//	cout << "position= " << position << endl;
		//}



		/*   查找字符串中的','*/
		//char line1[] = { "123,456,7891455" };
		//cout << "从字符串的第0位开始寻找" << endl;
		//char *p = line1;
		//while (*p != '\0')
		//{
		//	if (*p == ',')
		//	{
		//		cout << "position= " << position << endl;	
		//    }
		//	position++;
		//	p++;
		//}


		
		
	
	}

	fs.close();



}




int main()
{

	//write_file();
	//test02();
	//test03();
	//test04();
	test05();
	test06();
}

2.2 第二版代码

/* 2022 08 11 */

//预备知识
//fstream  // 文件流
//ifstream  // 输入文件流 in
//ofstream  // 输出文件流 out


//ios::in:文件以输入方式打开(文件数据输入到内存)

//ios::out:文件以输出方式打开(内存数据输出到文件)

//ios::app:以追加的方式打开文件

//ios::ate:文件打开后定位到文件尾,ios:app就包含有此属性

//ios::trunc:如果文件存在,把文件长度设为0

//ios::binary:以二进制方式打开文件,缺省的方式是文本方式

//ios::nocreate:不建立文件,所以文件不存在时打开失败

//ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败


//  To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
//  在VS2013中,使用提示中的_CRT_SECURE_NO_WARNINGS,以下是使用方法:
//	1.项目属性—— > C / C++—— > 预处理器—— > 预处理器定义。
//	2. 点击后栏。
//	3.输入:_CRT_SECURE_NO_WARNINGS(与前面的要用分号分开,后面加分号)
//或者采用宏定义


#define _CRT_SECURE_NO_WARNINGS  //出现安全警告 放置在头文件顶部
#include
#include
#include
#include
using namespace std;
void write_file1()//写文件
{
	srand((unsigned int)time(NULL));

	ofstream file1;
	file1.open("car.csv", ios::app);      //   所有输出附加在文件末尾,用追加的方式写入,
	                                     //   写入追加的结果以换行的方式往下添加
		if (file1.is_open())
		{
			cout << "正确打开文件! " << endl;
			for(int i=0;i<10;i++)
			file1 << rand() % 10 << endl;

		}
	file1.close();

}

void read_file1()//一行一行读文件
{
	ifstream file1;
	string _str;
	file1.open("car.csv");
	if (file1.is_open())
	{
		cout << "正确打开文件! " << endl;
		//一行一行读
		if (file1.is_open())
		{
			while (getline(file1, _str,','))//用法:接收一个字符串,可以接收空格并输出,需包含“#include
			{
				cout << _str << endl;
			}
				

		}
	}





}

void write_file2_NoAdd()  //文件写入(不追加,覆盖原文件)
{
	//1、创建流对象
	fstream file; //可输入输出
	//2、指定打开方式
	file.open("A1.txt", ios::out);
	//3、文件写入
	file << "abc256JKJKKJ" << " " << 123 << endl;//中间要有空格才能识别字符串与数字
	file.close();
}

void read_file2()  //测试将字符串与数字分开输出
{
	//1、创建流对象
	fstream file; //可输入输出
	//ifstream file; //可输入
	//2、指定打开方式
	file.open("A1.txt", ios::in);
	//3、文件读取(前面是字符串,后面是数字)"abc256"123
	string s;
	int num;
	if (file.is_open())
	{
		cout << "正确打开文件! " << endl;

		while (file >> s >> num) //文件读取至末尾
		{
			cout << s << endl << num << endl;
		}

	}

	file.close();
}


void write_file3()
{
	//1、创建流对象
	fstream fs; //可输入输出 "123,456,789"
	//2、指定打开方式
	fs.open("stringNum.txt",ios::out);
	//3、文件写入
	fs << "123,456,789" << endl;
	fs.close();
	cout << "正确写入文件!" << endl;
}


void read_file3()//"123,456,789"
{
	//1、创建流对象
	fstream fs; //可输入输出
	//2、指定打开方式
	fs.open("stringNum.txt", ios::in);//ios::in:文件以输入方式打开(文件数据输入到内存)
	//cout << "打开文件前! " << endl;
	//3、文件读取(前后都是数字)
	if (fs.is_open())
	{
		cout << "正确打开文件! " << endl;
		string line;//准备一个空字符串
		string::size_type position;//写成int也行
		position = 0;
		while (fs >> line) 
		{

			cout << line ;
			
		}
		//cout << line ;
		
		//使用string::find函数的缺点:遇见','就会终止
		//if ((position = line.find(',', position)) != string::npos) //如果没找到,返回一个特别的标志c++中用npos表示,我这里npos取值是4294967295,写成-1也行,计算机中和npos相等
		//{
		//	cout << "从字符串的第0位开始寻找" << endl;
		//	cout << "position= " << position << endl;
		//}



		
		
		
		

		 	


		/*   查找字符串中的','*/
		//使用测试数组
		//char name_line[25] = { "123,456,7891455" };//使用字符数组
		//char *p = name_line;
		//cout << "从字符串的第0位开始寻找" << endl;
		//while (*p != '\0')
		//{
		//	if (*p == ',')
		//	{
		//		cout << "position= " << position << endl;	
		//    }
		//	position++;
		//	p++;
		//}




		// c_str()函数  //这里还要重写
		char ps[20]="aaaa";
		strcpy(ps,line.c_str());

		//cout << ps << endl;
		cout << "从字符串的第0位开始寻找" << endl;
		char *pd = ps;
		while (*pd != '\0')
		{
			if (*pd == ',')
			{
				cout << "position= " << position << endl;	
		    }
			position++;
			pd++;
		}










	}

	fs.close();



}
void test07()
{

	string s = "aaaavvva";
	char a[10];
	//strncpy_s(a, s.c_str(), s.length() + 1);//必须加1,\0还占一个位置
	strcpy_s(a, s.c_str());//区分strncpy_s和strcpy_s
	for (int i = 0; i < 10; i++)
		cout << a[i] << " ";
	cout << endl;

}

void test08()
{
	//const char* c; //①
    //char* c;       //②
    //char c[20]; 
	char* c = new char[20];
	string s = "1234";
	//c = s.c_str(); 
	strcpy(c, s.c_str());
	cout << c << endl; //输出:1234
	s = "abcd";
	cout << c << endl; //输出:1234



}

int main()
{

	//write_file1();//写文件
	//read_file1();//一行一行读文件
	//write_file2_NoAdd();//文件写入(不追加,覆盖原文件)
	//read_file2();


	
	write_file3();
	read_file3();

	//test07();
	//test08();

}

二、补充部分 C++:cin、cin.getline()、getline()的用法

主要内容:

  1. cin用法
  2. cin.getline()用法
  3. getline()用法

注意的问题

1、cin>>

用法1:输入一个数字或字符

#include 
using namespace std;
int main ()
{
int a,b;

cin>>a>>b;

cout<<a+b<<endl;
}

用法2:接收一个字符串,遇“空格”、“TAB”、“回车”就结束

#include 
using namespace std;
int main ()
{

char a[20];
cin>>a;
cout<<a<<endl;
}

输入:jkljkljkl
输出:jkljkljkl

输入:jkljkl jkljkl //遇空格结束
输出:jkljkl

2、cin.getline()

用法:接收一个字符串,可以接收空格并输出

#include 
using namespace std;
int main ()
{
	char m[20];
	cin.getline(m,5);
	cout<<m<<endl;

}

输入:jkljkljkl
输出:jklj

接收5个字符到m中,其中最后一个为’\0’,所以只看到4个字符输出;

如果把5改成20:
输入:jkljkljkl
输出:jkljkljkl

输入:jklf fjlsjf fjsdklf
输出:jklf fjlsjf fjsdklf

延伸:
1、cin.getline()实际上有三个参数,cin.getline(接收字符串的变量,接收字符个数,结束字符)
2、当第三个参数省略时,系统默认为’\0’
3、如果将例子中cin.getline()改为cin.getline(m,5,‘a’);当输入jlkjkljkl时输出jklj,输入jkaljkljkl时,输出jk

3、getline()

用法:接收一个字符串,可以接收空格并输出,需包含

#include  

示例代码

#include
#include
using namespace std;
int main ()
{
	string str;
	getline(cin,str);
	cout<<str<<endl;
}

输入:jkljkljkl
输出:jkljkljkl

输入:jkl jfksldfj jklsjfl
输出:jkl jfksldfj jklsjfl

你可能感兴趣的:(C++笔记,c++,开发语言,算法)