草庐IT

C语言——读写TXT文件中的(多行多列矩阵型)浮点型数据的两种方式

@曾记否 2024-01-07 原文

C语言——读写TXT文件中的(多行多列矩阵型)浮点型数据

将要提取的数据


方式一:将数据按行读取并写入到结构体数组中

文本行输入函数:fgets(读文本)
函数原型

char *fgets(char *str, int n, FILE *stream);

参数
str– 这是指向一个字符数组的指针,该数组存储了要读取的字符串。
n– 这是要读取的最大字符数(包括最后的空字符)。通常是使用以 str 传递的数组长度。
stream– 这是指向 FILE 对象的指针,该 FILE 对象标识了要从中读取字符的流。
功能
从指定的流 stream 读取一行,并把它存储在str所指向的字符串内。当读取(n-1)个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。
其他读取文件的方式请看我的另一篇博客C语言文件读写操作

读取一个文件中的数据

//wm_e, wm_d, wm_u, vm_e, vm_d, vm_u, t_c
struct imuFile
{
	double wm_e;	 
	double wm_d;
	double wm_u;			 
	double vm_e; 
	double vm_d; 
	double vm_u; 
	double t_c;	
};

	struct imuFile imu[M] = { 0 };//创建结构体 
	FILE* fp = fopen("imu.txt", "r");// 打开文件,读文件
	if (fp == NULL) {
		fprintf(stderr, "文件打开失败.\n");
		exit(EXIT_FAILURE);
	}
	
	char row[N];
	int i = 0;
	while (fgets(row, N, fp) != NULL) {
			//printf("%s", row);//
			sscanf(row,"%lf	%lf	%lf	%lf	%lf	%lf %lf", &imu[i].wm_e, &imu[i].wm_d, &imu[i].wm_u, &imu[i].vm_e, &imu[i].vm_d, &imu[i].vm_u, &imu[i].t_c);//把数据存入结构体数组 
			//printf("%1.5e\t%1.5e\t%1.5e\t%1.5e\t%1.5e\t%.7lf\t%.2lf\n", imu[i].wm_e, imu[i].wm_d, imu[i].wm_u, imu[i].vm_e, imu[i].vm_d, imu[i].vm_u, imu[i].t_c);//
			i++;
			}
	fclose(fp);
	return 0;
}		

读取两个文件中的数据

#define N 85
#define M 9999

//wm_e, wm_d, wm_u, vm_e, vm_d, vm_u, t_c
struct imuFile
{
	double wm_e;	 
	double wm_d;
	double wm_u;			 
	double vm_e; 
	double vm_d; 
	double vm_u; 
	double t_c;	
};

//att1, att2, att3, vn_e, vn_d, vn_u, pos_e, pos_d, pos_u
struct gpsFile
{
	double att1;
	double att2;
	double att3;
	double vn_e;
	double vn_d;
	double vn_u;
	double pos_e;
	double pos_d;
	double pos_u;
};

	struct imuFile imu[M] = { 0 };//创建结构体 
	struct gpsFile gps[M] = { 0 };//创建结构体 

	FILE* fp = fopen("imu.txt", "r");// 打开文件,读文件
	if (fp == NULL) {
		fprintf(stderr, "文件打开失败.\n");
		exit(EXIT_FAILURE);
	}

	FILE* fpgps = fopen("gps.txt", "r");// 打开文件,读文件
	if (fpgps == NULL) {
		fprintf(stderr, "文件打开失败.\n");
		exit(EXIT_FAILURE);
	}

	char row[N];
	char row_gps[N];
	int i = 0;
	while (fgets(row, N, fp) != NULL && fgets(row_gps, N, fpgps) != NULL) {
			//printf("%s", row);//
			sscanf(row,"%lf	%lf	%lf	%lf	%lf	%lf %lf", &imu[i].wm_e, &imu[i].wm_d, &imu[i].wm_u, &imu[i].vm_e, &imu[i].vm_d, &imu[i].vm_u, &imu[i].t_c);//把数据存入结构体数组 
			sscanf(row_gps, "%lf	%lf	%lf	%lf	%lf	%lf %lf	%lf %lf", &gps[i].att1, &gps[i].att2, &gps[i].att3, &gps[i].vn_e, &gps[i].vn_d, &gps[i].vn_u, &gps[i].pos_e, &gps[i].pos_d, &gps[i].pos_u);
			//printf("%1.5e\t%1.5e\t%1.5e\t%1.5e\t%1.5e\t%.7lf\t%.2lf\n", imu[i].wm_e, imu[i].wm_d, imu[i].wm_u, imu[i].vm_e, imu[i].vm_d, imu[i].vm_u, imu[i].t_c);//
			}

	fclose(fp);
	fclose(fpWrite);
	
	return 0;
}		

报错解决:0x00007FF6C90AB2C7 处有未经处理的异常(在 sfann_sins.exe 中): 0xC00000FD: Stack overflow (参数: 0x0000000000000001, 0x00000040B0203000)。


原因:数组太大,栈空间不够用导致栈溢出!!!
解决办法:调试——》调试属性——》连接器——》系统——》修改堆栈保留/提交大小


> 读取大量数据时不建议使用结构体数组的方式输出!!!建议使用动态内存扩展的方式

方式二:将数据按行读取并写入到malloc数组中

创建变量或者数组就是我们常见的内存开辟方式

int num = 100;//开辟4个字节的空间
int arr[10] = {0};//开辟40个字节的连续空间

上面开辟空间的方式有两个特点:

  1. 开辟的空间大小是固定的,也就是不能修改的。
  2. 数组在声明的时候,必须知道数组长度,它所需要的内存在编译时就已经分配好了。

但是很多时候,我们对于空间的需求上面的两种情况是满足不了的,有的时候我们需要的内存大小要程序运行之后才能知道,或者说有时候数组大小空间不够了,那么数组编译时开辟的内存空间的方式就不可行了,这个时候就需要动态内存开辟了。

注意:动态开辟的内存是在上的,而我们使用的局部变量和函数的形参是在上开辟空间。

malloc函数使用形式

关于malloc所开辟空间类型:malloc只开辟空间,不进行类型检查,只是在使用的时候进行类型的强转。
举个例子:‘我’开辟你所需要大小的字节大小空间,至于怎么使用是你的事
mallo函数返回的实际是一个无类型指针,必须在其前面加上指针类型强制转换才可以使用

指针自身 = (指针类型*)malloc(sizeof(指针类型)*数据数量)
int *p = NULL;
int n = 10;
p = (int *)malloc(sizeof(int)*n);

在使用malloc函数之前我们一定要计算字节数,malloc开辟的是用户所需求的字节数大小的空间。

free函数

作用:释放malloc(或calloc、realloc)函数给指针变量分配的内存空间。
注意:使用后该指针变量一定要重新指向NULL,防止悬空指针(失效指针)出现,有效规避错误操作。

int main()
{
	int *p = (int *)malloc(sizeof(int));
	*p = 100;
	free(p);
	p = NULL;
	return 0;

free函数在释放空间之后,把内存前的标志变为0,且为了防止数据泄露,它会把所释放的空间用cd进行填充。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N_imu 100
int main()
{
	FILE* fp = fopen("imu.txt", "r");// 打开文件,读文件
	if (fp == NULL) {
		fprintf(stderr, "文件打开失败.\n");
		exit(EXIT_FAILURE);
	}

	char* row = (char*)malloc(sizeof(char) * N_imu);
	double* ptr = (double*)malloc(sizeof(double) * 7);

	if (ptr == NULL)
	{
		printf("开辟内存失败!\n");
	}
	else
	{
		while (fgets(row, N_imu, fp) != NULL) {
			//printf("%s", row);//
			sscanf(row, "%lf	%lf	%lf	%lf	%lf	%lf %lf", ptr, ptr + 1, ptr + 2, ptr + 3, ptr + 4, ptr + 5, ptr + 6);
			int i = 0;
			for (i = 0; i < 7; i++)
			{
				printf("%.5e\t", *(ptr + i));
			}
			printf("\n");
		}
	}

	free(ptr);//释放空间
	free(row);
	ptr = NULL;//指向NULL
	row = NULL;
	
	return 0;
}

读取两个文档中的数据

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N_imu 100
#define N_gps 110   //尽可能比数据中的字符串大一些,否则会出现某些行的字符串大于指定长度时,重复打印的问题!!!!!

int main()
{
	FILE* fp = fopen("imu.txt", "r");// 打开文件,读文件
	if (fp == NULL) {
		fprintf(stderr, "文件打开失败.\n");
		exit(EXIT_FAILURE);
	}
	
	FILE* fp_gps = fopen("gps.txt", "r");
	if(fp_gps == NULL){
		fprintf(stderr, "文件打开失败.\n");
		exit(EXIT_FAILURE);
	}
	
	char* row = (char*)malloc(sizeof(char) * N_imu);
	char* row_gps = (char*)malloc(sizeof(char) * N_gps);
	double* ptr = (double*)malloc(sizeof(double) * 7);
	double* ptr_gps = (double*)malloc(sizeof(double) * 9);
	if (ptr == NULL && ptr_gps == NULL)
	{
		printf("开辟内存失败!\n");
	}
	else
	{
		while (fgets(row, N_imu, fp) != NULL && fgets(row_gps, N_gps, fp_gps) != NULL) {
			//printf("%s", row);//
			sscanf(row, "%lf	%lf	%lf	%lf	%lf	%lf %lf", ptr, ptr + 1, ptr + 2, ptr + 3, ptr + 4, ptr + 5, ptr + 6);
			sscanf(row_gps, "%lf	%lf	%lf	%lf	%lf	%lf %lf	%lf %lf", ptr_gps, ptr_gps + 1, ptr_gps + 2, ptr_gps + 3, ptr_gps + 4, ptr_gps + 5, ptr_gps + 6, ptr_gps + 7, ptr_gps + 8);
			int i = 0;
			for (i = 0; i < 7; i++)
			{
				printf("%.5e\t", *(ptr + i));
			}
			printf("\n");
			int j = 0;
			for (j = 0; j < 9; j++)
			{
				printf("%.5e\t", *(ptr_gps + j));
			}
			printf("\n");
		}
	}
	free(ptr);//释放空间
	free(row);
	ptr = NULL;//指向NULL
	row = NULL;

	return 0;
}

输出TXT文件

FILE* fpWrite = fopen("avpt.txt", "w");// 打开文件,写文件
	if (fpWrite == NULL)
	{
		return 0;
	}
while (fgets(row, N_imu, fp) != NULL) {
	//printf("%s", row);//
	sscanf(row, "%lf	%lf	%lf	%lf	%lf	%lf %lf", ptr, ptr + 1, ptr + 2, ptr + 3, ptr + 4, ptr + 5, ptr + 6);
	int i = 0;
	for (i = 0; i < 7; i++){
		fprintf(pfWrite, "%1.5e\t", *(ptr + i));
	}
	printf("\n");

有关C语言——读写TXT文件中的(多行多列矩阵型)浮点型数据的两种方式的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  4. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  5. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  8. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  9. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  10. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

随机推荐