这世间,青山灼灼,星光杳杳,秋风渐渐,晚风慢慢
文件操作编程
本专栏参考教材是四川轻化工大学陈年老师的linux实验指导手册(含学习通的一些程序笔记)。
1)熟悉Linux的C编程环境
linux的基本c开发环境由以下几部分组成:c程序库glibc,c编译器 gcc或cc,系统头文件glibc_header,库文件、包含文件存放在/usr/lib目录下。
编译连接可用以下的命令进行,假定源程序有两个文件分别是f1.c,f2.c,生成的可执行文件名为hello.exe,缺省目标名称的时候,gcc 编译出来的文件是a.out,用“-o”选项可以指定输出文件名,例:
#gcc -o hello.exe fi.c f2.c
编译优化
参数-O1、-O2、-O3中,随着数字变大,代码的优化程度也越高,可调试性越低
“-o”选项可以指定输出文件名
gcc optimize.c -o optimize # 进行编译的优化
time ./optimize #用于 查看二进制文件的运行时间
gcc –O optimize.c -o optimize
time ./optimize
对比两次执行的输出结果。
参考程序optimize.c :
#include <stdio.h>
int main(void)
{
double counter;
double result;
double temp;
for (counter = 0; counter < 2000.0 * 2000.0 * 2000.0 / 20.0 + 2020;
counter += (5 -1) / 4) {
temp = counter / 1979;
result = counter;
}
printf(“Result is %lf\n”, result);
return 0;
}
l 学习用gdb跟踪调试程序的方法。
l 学习makefile的写法和使用(选作)。
2)文件基本操作编程
使用Linux系统调用编写一个完成文件拷贝的C程序。比较拷贝得到的文件与源文件的大小和内容(命令diff,cmp)。8.c
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h> //用于open
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> //用于close,read,write
int main(int argc, char *argv[])
{
//定义变量
int fd_src, fd_obj; // fd_src表示源文件,fd_obj表示目标文件
char buf[32] = {0}; //定义一个buf来放读出的字符,[32]:有32字节的空间,{0}:已清零,先用ll a.txt来确定长度,再决定写多少
ssize_t ret; // read的返回值是ssize_t型
//打开a.txt
fd_src = open("./a.txt", O_RDWR); // O_RDWR 读写方式打开
//打开b.txt,没有就创建
fd_obj = open("./b.txt", O_CREAT | O_RDWR, 0666); // O_RDWR 读写方式打开, O_CREAT 文件不存在则创建;0666:0表示八进制,666表示权限
//读写操作
while ((ret = read(fd_src, buf, 32)) != 0)
{
write(fd_obj, buf, ret); //在b.c里写入a.c里面读的内容,ret表示字节数,要配合O_RDWR使用
}
printf("写好了\n");
//关闭
close(fd_src);
close(fd_obj);
}
结论:a.txt和b.txt文件内容一样
编写C程序完成:创建一个新文件,输入一段数据,然后随机移动指针接着插入一段数据。完成后,查看该文件的大小和内容。怎样获取当前文件的读写指针位置?9.1.c
//确定当前指针位置
a=lseek(fd,0,SEEK_CUR);
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h> //用于open,<sys/types.h>还用于lseek
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> //用于close,read,write,lseek
int main(int argc, char *argv[])
{
//定义变量
int fd;
//打开9.txt
fd = open("./9.txt", O_CREAT | O_RDWR); // O_RDWR 读写方式打开
lseek(fd, 5, SEEK_SET); //把指针移第5个字节
write(fd, "world", 5); //在9.txt里写入world,5表示字节数,要配合O_RDWR使用
printf("写好了\n");
close(fd); //关闭
}
3)编写拷贝命令,实现文件或目录的复制。
命令功能要能够完成实际应用的要求,实现拷贝命令的各项功能(参考cp命令的功能和用法),如:单参数、双参数等各种参数格式的识别,文件的连接,目录下内容的递归复制,拷贝时磁盘空间的检查等,目标文件重名的提示等。13.c
设计中要注意:
Ø 结合系统拷贝实际进行认真地分析,确定设计的拷贝命令要实现的各种复制功能、输入形式,错误处理方法;
Ø 在上一步基础上确定出拷贝命令的实际需要,设计命令的基本功能、程序结构和处理流程,学习和选择合理的系统调用;
Ø 做出必要的流程图和程序说明;
Ø 编写各基本功能代码;
Ø 运行调试,验证程序功能,反复修改自己的设计和实现;
Ø 完成拷贝程序设计。
#include <sys/types.h> //用于mkdir,opendir
#include <dirent.h>
#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h> //用于close,read,write
int main(int argc, char *argv[])
{
//定义变量
int fd_src, fd_obj; // fd_src表示源文件,fd_obj表示目标文件
char buf[128] = {0}; //定义一个buf来放文件内容,[32]:有32字节的空间,{0}:已清零
char file_path[128] = {0}; //定义一个file_path来放输入的目录
char file_name[128] = {0}; //表示要拷贝的文件
char file_name2[128] = {0};
ssize_t ret; // read的返回值是ssize_t型
DIR *dp; // opendir返回的是指针
struct dirent *re; // readdir返回
printf("输入需要拷贝的目录:");
scanf("%s",file_path);
dp = opendir(file_path); //打开由键盘输入的目录
if (dp != NULL)
printf("已打开%s的目录\n", file_path);
while (1) //用于循环读取目录里面的文件名
{
re = readdir(dp); //读取目录
if (re == NULL)
{
printf("没有内容了\n");
break;
}
else if (re->d_name[0] == '.') // 如果文件名字以 . 开头的则为隐藏文件, 选择直接忽略
{
continue;
}
else
printf("文件:%s\n", re->d_name);
}
printf("输入需要拷贝的文件及其路径(如j/1.txt):");
scanf("%s", file_name);
printf("输入需要拷贝到的路径及其文件名(如j/1.txt):");
scanf("%s", file_name2);
//打开需要拷贝的文件
fd_src = open(file_name, O_RDWR); // O_RDWR 读写方式打开
//打开被写入的文件,没有就创建
fd_obj = open(file_name2, O_CREAT | O_RDWR, 0666); // O_RDWR 读写方式打开, O_CREAT 文件不存在则创建;0666:0表示八进制,666表示权限
if(fd_obj<0)
printf("新文件没\n");
//读写操作
while ((ret = read(fd_src, buf, 128)) != 0)
{
write(fd_obj, buf, ret); //在目标里写入源里面读的内容,ret表示字节数,要配合O_RDWR使用
}
if ((read(fd_obj, buf, 32)>0))
printf("写好了\n");
//关闭文件
close(fd_src);
close(fd_obj);
closedir(dp); //关闭目录
}
4)gdb调试工具
Linux包含了一个叫gdb的GNU调试程序,能在程序运行时观察程序的内部结构和内存的使用情况。它具有以下一些功能:
·监视程序中变量的值;
·设置断点以使程序在指定的代码行上停止执行;
·一行行的执行代码。
以下是利用gdb进行调试的步骤:
必须使程序在编译时包含调试信息。调试信息里包含程序里的每个变量的类型和在可执行文件里的地址映射以及源代码的行号。gdb利用这些信息使源代码和机器码相关联。在编译时用-g选项打开调试选项。
gdb基本命令:
命 令 | 命令缩写 | 描 述 |
---|---|---|
file | 装入欲调试的可执行文件 | |
kill | k | 终止正在调试的程序 |
list | l | 列出产生执行文件的源代码部分 |
next | n | 执行一行源代码但不进入函数内部 |
step | s | 执行一行源代码并进入函数内部 |
run | r | 执行当前被调试的程序 |
quit | q | 终止gdb |
watch | 监视一个变量的值而不管它何时被改变 | |
break | b | 在代码里设置断点,使程序执行到这里时被挂起 |
display | disp | 跟踪查看变量 |
info | i | 描述程序状态,info break查看断点 |
delete | d | 删除断点d num(断点编号) |
clear | 清除指定行号的断点 | |
p | 打印内部变量的值 | |
congtinue | c | 继续程序运行 |
set var | 设置变量的值 | |
backtrace | bt | 查看函数调用信息 |
frame | f | 查看栈帧 |
start | st | 执行程序至main()函数第一条指令 |
finish | 结束函数 | |
shell | 不离开gdb就执行Linux/UNIX shell 命令 |
l 学习使用gbd来完成程序跟踪调试的基本方法并记录总结。
5、实验报告
要求认真书写实验报告,报告的内容包括:实验目的、实验内容、实验步骤、实验结果等。
学习通作业
1. linux用文件操作系统调用编程打开已有文件 /exsample/exmb.conf,在文件末尾添加“path = /home”。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <fcntl.h>
int main()
{
int fd;
fd = open("/exsample/exmb.conf", O_WRONLY | O_APPEND); //打开文件
write(fd, "path = /home", 12); //写数据
close(fd); //关闭
}
2 . 用文件操作系统调用编程实现将已有文件/exsample/filea逆序。
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
char buf[128]; //缓冲区
int fd = open("/exsample/filea", O_RDONLY); //只读
int ret = lseek(fd, 0, SEEK_SET);
ret = read(fd, buf, sizeof(buf)); //返回读出数据
for (int i = strlen(buf) - 1; i >= 0; i--) //放入,倒序输出 strlen用于计算字符串长度
printf("%c", buf[i]);
return 0;
}
文章来源:https://www.toymoban.com/news/detail-400168.html
文章来源地址https://www.toymoban.com/news/detail-400168.html
到了这里,关于文件操作编程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!