c语言内存和文件处理有关知识
内存
分配内存的函数calloc,malloc
定义于头文件 <stdlib.h> | 功能 |
---|---|
malloc | 分配内存(函数) |
calloc | 分配并清零内存(函数) |
realloc | 扩充之前分配的内存块(函数) |
free | 归还还之前分配的内存(函数) |
aligned_alloc(C11) | 分配对齐的内存(函数) |
函数原型
void *malloc(unsigned int size) //注意使用时,若要4个int类型数据空间需要使用:4*sizeof(int)也就是16
void* calloc( size_t num, size_t size ); //这里参数则是(4,sizeof(int)),参数规定把数量和数据类型分开
其中数据类型size_t可以简单理解为一个无符号整型,
主要是 malloc 和 calloc 的区别。 calloc 会申请内存,并全初始化为 0;而 malloc 只申请内存,并不作初始化。
#include <stdio.h>
#include <stdlib.h> int main(void)
{int *p1 = malloc(4*sizeof(int)); // 足以分配 4 个 int 的数组int *p2 = malloc(sizeof(int[4])); // 等价,直接命名数组类型int *p3 = malloc(4*sizeof *p3); // 等价,免去重复类型名if(p1) {for(int n=0; n<4; ++n) // 置入数组p1[n] = n*n;for(int n=0; n<4; ++n) // 打印出来printf("p1[%d] == %d\n", n, p1[n]);}free(p1);free(p2);free(p3);
}
可以利用这种动态分配内存和scanf函数得到一个动态长度的数组
代码
#include <stdio.h>
#include <stdlib.h>int main()
{int n=0,i;int *pa;printf("请输入数组长度:");scanf("%d",&n);pa = (int *)calloc(n,sizeof(int)); //指针指向分配空间的首地址for(i=0;i<n;i++){scanf("%d",&pa[i]);}for(i=0;i<n;i++){printf("输入的数据是:%d\n",pa[i]);}free(pa); //释放pa指针for(i=0;i<n;i++){printf("输入的数据是:%d\n",pa[i]); //这里的指针将指向不定的地址}system("pause");return 0;
}
文件操作fopen,fclose,FIL
遇到的问题总结
1. 字符串使用双引号"",字符赋值使用单引号'',(长时间不用c忘了)2. 判断语句(fp=fopen("fiel.txt","r+"))==NULL;的括号不能少,否则会出现先逻辑判断后赋值,这样编译不通过3. 判断读取文件是否正确一定使用"r"或"r+"模式,因为另外模式都会新建,4. 在打开文件读取后想要写入,"一定"使用fseek定位文件指针才行5. 一个奇怪的现象,a+模式:写入只是指针移动,不能修改本来的文本;但读取可以从全部文本最开始6. 字符串的写入都是自动在结尾包含了\0结束字符,所以指针会比字符串多移动一位7. 在r+模式下既可以对原始文本插入,也可以读取,但写入也要满足第4条
文件打开函数的模式
FILE *fp;
fp = fopen("路径","打开方式")
对文本字符操作的函数
具体功能可查看:https://zh.cppreference.com/w/c/io
函数使用实例
如果文件不存在可能会导致编译出现,run: line 1: 3 Segmentation fault (core dumped) ./a.out
Exited with error status 139
读取命令实例
file.txt
123456789
#include <stdio.h>
#include <stdlib.h>int main(void){FILE *fp;char f_getc,f_gets[4],f_read[4],f_scanf[4]; char f_getc,f_gets[5],f_read[8],f_scanf[4]; //换成这句就和预期结果一样了 fp = fopen("file.txt","r");f_getc = fgetc(fp);printf("fgetc: %c\n",f_getc);rewind(fp);fgets(f_gets,5,fp); //这里的“一定”要是一个字符串数组printf("fgets:%s\n",f_gets); //得到n-1个字符,最后一个自动填充\0fflush(fp);fseek(fp,0,0);fread(f_read,sizeof(char),3,fp); //这里读取有问题,但单独使用没问题printf("fread: %s\n",f_read);//fflush(fp);rewind(fp);fscanf(fp,"%s",f_scanf); printf("f_scanf: %s\n",f_scanf);fclose(fp);printf("*************************************");printf("文件中全部字符!!!\n");system("type file.txt "); //这里会全部显示一次printf("\n");system("pause"); return 0;
}
参考:https://editor.csdn.net/md/?articleId=128229605
参考:https://zh.cppreference.com/w/c/io,https://blog.csdn.net/qq_26768741/article/details/50933598,https://blog.csdn.net/qq_45858169/article/details/103704389
经过尝试和查找资料发现,确实是有缓存中字符的问题,也有一个错误的地方,fread是针对读取的二进制流文件读取,但不是造成这种显示的主要原因;而最主要的原因是读取字符的数组不够,导致读取数据时,没有将终止符或回车符放入字符串,导致输出时在变成输出缓存中读取了数据,为了深入解释这个输出异常的原因,单独分开一个文件中,测试和分析
文件字符写入
txt文件中的初始值123456789;执行后,值是mqnzxxxx9,
#include <stdio.h>
#include <stdlib.h>int main(void){FILE *fp;char sca,fpri[5]={'m','q','n','z'},fwri[5]={'x','x','x','x'};fp = fopen("file.txt","r+"); //结尾追加字符fputc('b',fp);fputs("MAR",fp);rewind(fp); //到第一个字符fscanf(fp,"%c",&sca); //从文件中读取字符,而不是从键盘中// printf("sca: %c\n",sca);rewind(fp); //到第一个字符fprintf(fp,"%s",fpri); //写入文件中printf("%s\n",fpri);fwrite(fwri,sizeof(char),4,fp);fclose(fp);return 0;
}
“+”模式添加的不同
#include <stdio.h>
#include <stdlib.h>int main(void){FILE *fp;char b;//每次测试保证txt文件中只"有123456"这6个字符;fp=fopen("file.txt","a+"); //只仅仅修改这里的模式为a+和a,和保证txt开始文本只有123456rewind(fp); //指针在文件开始b = fgetc(fp);printf("第一次读:%c\n",b);fseek(fp,2,0);printf("第二次读:%c\n",fgetc(fp));fseek(fp,2,0);fputs("sag",fp);printf("第三次读:%c\n",fgetc(fp));fclose(fp);system("type file.txt "); //只是在cmd窗口显示文本内容,懒得每次打开txt查看printf("\n");system("pause"); return 0;
}
显示结果a+和a对比分析:
a模式没有读取数据的功能,但能写入,a+模式有读写的功能,但写指针和读指针不是同一位置,而且写文本时会同时移动两个指针,但会一直在文档结尾追加
a+可读写的文件出现的问题
一次写入命令后,若不定位指针,那么紧接着的读取命令也会写入;a+模式下,文档最后写入了6。因此,需要注意每次读取和写入文本命令转换时重新使用feek(fp,n,0)
定位
r+模式下
读和写命令转换时也会出现问题,
#include <stdio.h>
#include <stdlib.h>int main(void){FILE *fp;char a[4],b;fp=fopen("file.txt","r+");rewind(fp);b = fgetc(fp);printf("第一次读:%c\n",b);fseek(fp,2,0);printf("第二次读:%c\n",fgetc(fp));fseek(fp,1,0);fputs("sa",fp);//fseek(fp,2,0);printf("第三次读:%c\n",fgetc(fp));fclose(fp);system("type file.txt ");printf("\n");system("pause"); return 0;
}
下图中的,虽然是fgetc导致的5被写入,但通过fgetc写入的描述并不准确,只是将5读入缓存,而fputs函数在写入的字符串最后也自动添加换行“\n”和终止符“\0”,因此输入的字符变成了"sa5"
c语言内存和文件处理有关知识相关推荐
- c语言 内存映射文件,内存映射文件
内存映射文件 03/30/2017 本文内容 内存映射文件包含虚拟内存中文件的内容. 借助文件和内存空间之间的这种映射,应用(包括多个进程)可以直接对内存执行读取和写入操作,从而修改文件. 可以使用托 ...
- java流与文件——内存映射文件
[0]README 0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件--内存映射文件 的相关知识: 0.2)内存映射文件的目的是: 提高访问速度, 缓冲区Bu ...
- 【C 语言】文件操作 ( C 语言中的文件操作函数 | 磁盘与内存缓冲区 | 缓冲区工作机制 )
文章目录 一.C 语言中的文件操作函数 二.磁盘与内存缓冲区 三.缓冲区工作机制 一.C 语言中的文件操作函数 读取 文本文件 可以使用 getc , fgets , fscanf 函数 , 向 文本 ...
- 梓益C语言学习笔记之链表&动态内存&文件
梓益C语言学习笔记之链表&动态内存&文件 一.定义: 链表是一种物理存储上非连续,通过指针链接次序,实现的一种线性存储结构. 二.特点: 链表由一系列节点(链表中每一个元素称为节点)组 ...
- C语言文件联系人管理碎片整理,深入理解C语言内存管理.docx
深入理解C语言内存管理 之前在学Java的时候对于Java虚拟机中的内存分布有一定的了解,但是最近在看一些C,发现居然自己对于C语言的内存分配了解的太少. 问题不能拖,我这就来学习一下吧,争取一次搞定 ...
- C语言读取大文件的问题 内存映射
2019独角兽企业重金招聘Python工程师标准>>> [Ref] Windows对文件的读写提供了很丰富的操作手段,如: 1. FILE *fp, fstearm...; (C/C ...
- C/C++语言入门篇 -- 文件操作
最近实在是太忙了,这篇整整就推迟了1个月了,实在是对不起.之前本打算这个模块就结束了,文件操作就不写了,但是文件操作又是一个很重要的东西,而且也刚好能够总结之前我们学习的所有知识.同时也为了将文件操作 ...
- keil c语言pdf,Keil软件“C语言”与“汇编”混编 —— 相关知识整理.pdf
Keil软件"C语言"与"汇编"混编 -- 相关知识整理.pdf Keil 软件软件C 语言语言与与汇编汇编混编混编 相关知识整理相关知识整理 用 Keil 在 ...
- C语言零基础入门——1.基础知识与环境搭建。
C语言零基础入门--1.基础知识与环境搭建. 好了.终于迎来了第一篇文章,这篇文章要做的事情非常简单,主要有三个事情 第一:C语言的介绍. 第二:计算机的基础知识. 第三:C语言的环境安装 ...
最新文章
- Oracle—dmp表的导入导出
- c语言程序的实质,C语言_printf中的%p的实质
- 中过滤记录中时间_水肥一体化中常见的过滤器
- linux ip add address,linux – ip地址范围参数
- java线程 demo_Java多线程demo
- python list 查找子列_python – SQLAlchemy查询,其中列包含一个子字符串
- Alibaba Cloud Toolkit——简介
- C++11学习笔记-----线程库std::thread
- 真神器!在家也能控制公司的电脑了
- C++ typename的使用方式
- Tomcat(Install)
- Linux下 mysql5.7的彻底卸载
- WebSphere 集群环境下配置 Quartz集群
- PIC单片机入门教程(一)—— 准备工作
- 金万维未找到服务器信息,域名解析失败原因和问题排查方法
- 洛谷P4207 [NOI2005]月下柠檬树(计算几何+自适应Simpson法)
- MPU3050+加速度计数据处理
- Android adb启动错误,使用adb shell启动Android应用程序时出现错误“活动类不存在”...
- 龙贝格算法求解椭球周长
- 获取国家统计局行政区划数据(复制粘贴)