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

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

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


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::inifstream fstream打开文件用于读取数据。如果文件不存在,则打开出错。
ios::outofstream fstream打开文件用于写入数据。如果文件不存在,则新建该文件;如果文件原来就存在,则打开时清除原来的内容。
ios::appofstream fstream打开文件,用于在其尾部添加数据。如果文件不存在,则新建该文件。
ios::ateifstream打开一个已有的文件,并将文件读指针指向文件末尾(读写指 的概念后面解释)。如果文件不存在,则打开出错。
ios:: truncofstream打开文件时会清空内部存储的所有数据,单独使用时与 ios::out 相同。
ios::binaryifstream ofstream fstream以二进制方式打开文件。若不指定此模式,则以文本模式打开。
ios::in ios::outfstream打开已存在的文件,既可读取其内容,也可向其写入数据。文件刚打开时,原有内容保持不变。如果文件不存在,则打开出错。
ios::in ios::outofstream打开已存在的文件,可以向其写入数据。文件刚打开时,原有内容保持不变。如果文件不存在,则打开出错。
ios::in ios::outfstream打开文件,既可读取其内容,也可向其写入数据。如果文件本来就存在,则打开时清除原来的内容;如果文件不存在,则新建该文件。
ios::truncfstream打开文件,既可读取其内容,也可向其写入数据。如果文件本来就存在,则打开时清除原来的内容;如果文件不存在,则新建该文件。

注意事项:

  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<iostream>
#include<fstream>
#include<ctime>
#include<string>
#include<sstream>
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<string>”
			{
				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<sstream>
{
	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<iostream>
#include<fstream>
#include<ctime>
#include<string>
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<string>”
			{
				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 <iostream>
using namespace std;
int main ()
{
int a,b;

cin>>a>>b;

cout<<a+b<<endl;
}

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

#include <iostream>
using namespace std;
int main ()
{

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

输入:jkljkljkl
输出:jkljkljkl

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

2、cin.getline()

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

#include <iostream>
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<string>  

示例代码

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

输入:jkljkljkl
输出:jkljkljkl

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

  • 10
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 可以使用正则表达式来提取txt文本两个关键词之间的逗号隔开的坐标点信息。下面是一个示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <regex.h> int main() { FILE *fp; char *line = NULL; size_t len = 0; ssize_t read; fp = fopen("text.txt", "r"); if (fp == NULL) exit(EXIT_FAILURE); // 正则表达式匹配 char *pattern = "keyword1.*?,(.*?),.*?keyword2"; regex_t regex; int reti; reti = regcomp(&regex, pattern, REG_EXTENDED); if (reti) { fprintf(stderr, "Could not compile regex\n"); exit(EXIT_FAILURE); } // 逐行取文本文件 while ((read = getline(&line, &len, fp)) != -1) { regmatch_t pmatch[2]; reti = regexec(&regex, line, 2, pmatch, 0); if (!reti) { char *result; result = strndup(line + pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so); printf("%s\n", result); free(result); } } fclose(fp); if (line) free(line); return 0; } ``` 其,`text.txt`是需要提取信息的文本文件,`keyword1`和`keyword2`是需要匹配的关键词,间的逗号隔开的坐标点信息会被提取出来并输出。注意,在实际使用时需要根据文本文件的具体格式和需要匹配的关键词进行修改。 ### 回答2: 要提取txt文本两个关键词之间的逗号隔开的坐标点信息,可以通过以下步骤进行: 1. 取文本文件:使用C或C++编程语言文件输入操作,打开目标txt文件,并将其内容取到一个字符数组或字符串。 2. 定位关键词位置:在取到的文本,使用字符串处理函数(如strstr、strtok等)或正则表达式来定位第一个关键词和第二个关键词的位置。 3. 提取坐标点信息:在找到第一个关键词的位置后,搜索该位置之后的逗号(,)和下一个关键词的位置,提取两者之间的字符串。这个字符串将包含一个或多个坐标点信息。 4. 解析坐标点信息:将提取到的字符串逗号进行分割,得到每个坐标点的字符串表示。 5. 解析坐标值:对于每个坐标点的字符串表示,再按照特定规则(例如使用字符串处理函数strtod将字符串转换为浮点数),解析得到具体的坐标值。 6. 存储坐标点信息:将解析得到的坐标点信息存储到一个数据结构(例如数组或链表),方便后续处理和使用。 7. 输出坐标点信息:按照需要,将提取到的坐标点信息输出到文件或显示在屏幕上。 需要注意的是,在编程序时,要考虑异常情况,例如找不到关键词、关键词顺序颠倒、坐标点信息格式错误等,需要增加相应的错误处理机制,以保证程序的鲁棒性和正确性。 ### 回答3: 要提取txt文本两个关键词之间的逗号隔开的坐标点信息,可以使用C/C++编程语言进行处理。下面是一个简单的实现过程: 1. 首先,txt文本文件,将其存储到一个字符串。 2. 接下来,使用字符串处理函数来查找第一个关键词的位置。可以使用C/C++的strstr函数来查找字符串的子字符串位置。 3. 找到第一个关键词的位置后,再使用字符串处理函数来查找第二个关键词的位置。同样可以使用strstr函数来查找。 4. 在找到了两个关键词的位置后,接下来就是提取两个关键词之间的逗号隔开的坐标点信息了。可以使用字符串处理函数来截取这部分字符串。 5. 最后,将提取到的坐标点信息输出、打印或存储到另一个文件,以便后续使用。 需要注意的是,这只是一个简单的实现示例,具体的实现方式还需要根据实际的需求和文本格式进行调整。另外,错误处理和边界情况的处理也是需要考虑的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Love coldplay

你的鼓励,将让我持续更新

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值