scanf和fscanf读取文件
这篇是针对推箱子游戏而写的,某个时候在学C语言,最近转到windows设计,不知道是否有同样的感受,后面的东西学了,前面的就有点生疏了。其实,我的理解是,注意力转移了,当集中于当前问题的时候就会忽略以前的某些知识。这也说明,人的注意力是随着时间,学习内容的不同在起变化。但是,只要稍微复习一下就能很快恢复。
问题:比如一个文本文件的内容如下:
[1]
0000000000000000
0000000000000000
0000000000000000
0000011100000000
0000013100000000
0000012111100000
0001114243100000
0001324611100000
0001111410000000
0000001310000000
0000001110000000
0000000000000000
0000000000000000
0000000000000000
[2]
0000000000000000
0000000000000000
0001111100000000
0001622100000000
0001244101110000
0001242101310000
..................(截选)
[]内是序号,往下延伸,每个[]下面是14行16列的数据,我想获取给定的某个序号下面的这个二维数组数据,比如说,序号[10]下面的14*16列的数据。
————————————————————————————————————————————————————————————
在这个问题之前,首先理解一下流的概念,简易记录一下:
流有很多种,包括输入流,输出流等,这里只说输入流,比如stdin,在调用scanf函数读取这个流的时候,有几个需要注意的要点:
首先,scanf忽略前面的空格,回车等等字符
其次,在读取的时候,流中还有一个指针在不停的移动,也就是游标。做个图来说明:
想输入一个数据ABCD到字符串中,在开始的时候,故意敲入空格+回车键,这对scanf无影响,它会忽略,一直读取ABCD,又遇到一个回车,游标最终停留在回车这个字符上。
这个回车键被scanf获取了吗?其实是没有的,比如接下来可以用c=getchar(),就可以捕捉到这个回车字符。
同理,将stdin换成文件fp,一样遵循这个规则。因为不是专项整理流的问题,所以只简单概括到这。
————————————————————————————————————————————————————————
对于上题的解法是,从fp中读取一个字符串,然后和待匹配的序号比较,比如和字符串"[10]"比较,如果相等,则游标就定位在[10]之后的位置。
观察上面的文本文件,每一行之后就是一个回车,所以每次从fp中读取一个串,要么读的是[xx],要么读的就是二维数组的一行数据,当然,这个串的存储长度也至少大于一行的数据,至少为16个。
具体
首先获取要取的序号,定义一个字符串,将之写入其中。
char str[];
sprintf(str,"[%d]",n);
接着,按串读取fp,与之相比较。
FILE *fp=fopen("map.txt","rb"); //打开文本文件
if(fp==NULL)
return;
char data[];
fscanf(fp,"%s",data);//先读入一个串
while(strncmp(str,data,strlen(str))!=)//相等返回0
{
if(fscanf(fp,"%s",data)==NULL)//循环读取,游标也在移动
break;
}
假如读取到[10],符合题意了,则游标就正停留在[10]的后面,下面就是[10]序号下的14*16的数据。这个地方还有一个用处,比如说,一共有40关,假如玩家通关了,再扫描文件肯定找不到[41]的序号,就可以判定玩家通关了。
因为要读取14*16,相当于二维数组,处理如下:
for(int y=;y<;y++) //行
{
fscanf(fp,"%s",data);//读取一行
for(int x=;x<;x++)//列
{
map[y][x]=data[x]-'';//字符变整型,填充map[][],map[][]是一个整型的二维数组,所以需要转换
......
}
}
这样,问题就解决了。
完整的示例代码
void LoadMap(int n) //载入地图,主要负责填充map[][]的二维数组,map[][]是操纵画图的关键
{
char str[10];
sprintf(str,"[%d]",n);
FILE *fp=fopen("map.txt","rb"); //打开文件,读取地图数据,所谓地图,就是用数字来(标示)操纵位图块
if(fp==NULL)
return;
char data[20];
fscanf(fp,"%s",data);//先读入一个串
while(strncmp(str,data,strlen(str))!=0)//相等返回0
{
if(fscanf(fp,"%s",data)==NULL)//循环读取,游标也在移动
break;
}
for(int y=0;y<14;y++) //行
{
fscanf(fp,"%s",data);//读取14行
for(int x=0;x<16;x++)//列
{
map[y][x]=data[x]-'0';//字符变整型,填充map[][]
if(map[y][x]==MANATROAD||map[y][x]==MANATDESTINATION)
{
manposition.x=x;//人的位置
manposition.y=y;
}
}
}
fclose(fp);
}
*注:这段程序,每次都要扫描整个文件,获取与序号相同的串,由于文件比较小,影响也不是太大。
总结:对一个文本文件的搜索过程。
scanf和fscanf读取文件的更多相关文章
- C++/Php/Python/Shell 程序按行读取文件或者控制台
写程序经常需要用到从文件或者标准输入中按行读取信息,这里汇总一下.方便使用 1. C++ 读取文件 #include<stdio.h> #include<string.h> i ...
- C语言 读取文件中特定数据
//读取文件数据 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> struct jia ...
- Linux C 单链表 读取文件 并排序 实例并解释
C的指针挺头疼的,先看一个例子: 给指针赋值和通过指针进行赋值这两种操作的差别确实让人费解.谨记区分的重要方法是:如果对左操作数进行解引用,则修改的是指针所指对象的值: 如果没有使用解引用操作, ...
- C读取文件
C读取文件,这种写法不会多一行. #include "stdafx.h" #include <vector> using namespace std; struct P ...
- Loadrunner 读取文件
char buffer[1000]; long file_stream; char * filename = "d:\log.txt"; file_stream=fopen(fil ...
- 【C】一个读取文件记录器
分享一下!!! #include<stdio.h> #include<windows.h> #define N 70000 //定义行数!!用空间换取时间 struct stu ...
- Python读取文件数据
1题目要求: 文本文件有这些数据,需要的只有其中的5个属性,如下颜色标记 像以下的数据达到75万组: 1product/productId: B0000UIXZ4 2product/title: Ti ...
- 73.fseek与宽字符读取文件
fseek //文件路径 ] = "1.txt"; //FILE *pf = fopen(path, "a+");//尾部添加,文件指针在尾部 //FILE * ...
- C++/Php/Python/Shell 程序按行读取文件或者控制台方法总结。
C++/Php/Python/Shell 程序按行读取文件或者控制台方法总结. 一.总结 C++/Php/Python/Shell 程序按行读取文件或者控制台(php读取标准输入:$fp = fope ...
随机推荐
- Buffer I/O error on device sr0
Buffer I/O error on device sr0, logical block 0 I check today some old CDs, some of them were from ’ ...
- MySQL修改编码设置及乱码问题
源地址:http://blog.csdn.net/millia/article/details/5806774 昨天尝试把自己用php编写的第一个糙站发布到网上..结果出现了因为编码不统一而导致乱 ...
- UNION会自动删除重复项,union与union all的差异
UNION会自动删除重复项,刷选出部分字段的时候要注意了,如果刷选出来的两个字段的值完全相同就会剩下一个. UNION ALL 和 UNION 不同之处在于 UNION ALL 会将左右两个查询的结果 ...
- Python递归的经典案例
目录 : 一.递归的简介 二.递归的经典应用 2.1 递归求阶乘 2.2 递归推斐波那契数列 2.3 二分法找有序列表指定值 2.4 递归解汉诺塔 前言: 当我们碰到诸如需要求阶乘或斐 ...
- MySql ERROR 1045 (28000): Access denied 错误
[MySql ERROR 1045 (28000): Access denied 错误] 即登陆错误,使用MySql登陆时,需使正确的username/passwd.通过 -u -p 参数即可. My ...
- javaWeb后端学习记录
java后端学习重点: 1.java语言特性: 基础知识,集合,多线程,并发,JVM,NIO,网络编程,设计模式. (★★★★★) jdk源码中有大量的数据结构与java语言细节.jdk源码着重看c ...
- RigidBody组件的Is Kinematic
RigidBody组件的Is Kinematic属性打上勾(设为true,使其不受物理引擎驱动,Wall是为了防止其移动,Person是为了防止其受到力不断旋转—看的心塞=v=) .is kinema ...
- sqlserver查询效率 (转)
很多人不知道SQL语句在SQL SERVER中是如何执行的,他们担心自己所写的SQL语句会被SQL SERVER误解.比如: select * from table1 where name='zhan ...
- swift 移除所有子控件
/// 移除所有子控件 func removeAllSubViews(){ if self.view.subviews.count>0{ self.view.subviews.forEach({ ...
- Web Components 规范学习
最新的规范在这里:http://w3c.github.io/webcomponents/explainer/ 依据规范,有以下四个组成部分: Templates Custom Elements Sha ...