本篇主要讲一些linux系统下的程序如何运行
软件设计
编辑程序
在vscode中编写hello world程序,验证其在开发板中运行
#include<stdio.h>
int main (int argc,char *argv[])
{
printf("hello world\n");
return 0;
}
编译程序
需要在 Ubuntu 虚拟机加入共享文件夹,该共享文件夹就是编写代码所在的文件夹,因为要编译该代码,所以需要在共享文件夹中(注意:Ubuntu系统只做编译 )
添加共享文件夹后,在Ubuntu中要使用cd命令进入该文件夹
gec@ubuntu:~$ cd /mnt/hgfs/share/
进入文件夹后,可使用ls命令查看该文件下的目录,来验证是否有编写的代码文件,接着再进入该共享文件夹下的代码文件
gec@ubuntu:/mnt/hgfs/share$ cd V1.1.0.202312.2.alpha/
可使用ls命令在该文件下看到有编写的代码main.c文件
接着编译程序
…省略)V1.1.0.202312.2.alpha$ arm-linux-gcc main.c -o main
编译完后在该文件下可以看到有两个文件
main main.c
下载软件到目标板
使用tftp软件选择编译的程序所在的文件
使用windows的命令提示符去下载main程序到开发板中,需要在linux系统
其中192.168.64.2是window主机配置的ip地址
[root@GEC6818/IOT]#tftp 192.168.64.2 -g -l main
仿真调试
系统调试
运行代码需使用下面的命令
[root@GEC6818/IOT]#./main
当出现提示 -sh:./main:Permission denied 时,表示执行的软件出现权限不足的情况,因此需要使用下面的指令修改权限
root@GEC6818/IOT]#chmod 777 main
最后就在任务管理器中显示hello world
测试/修改
暂无
用户试用
暂无
项目结束
暂无
名字的录入
文件操作函数
对文件的操作有两种不同的方式,既可以使用由操作系统直接提供的编程接口 (API),即系统调用,也可以使用由标准C库提供的标准I/O函数
open()接口
//功能:打开或创建一个文件或设备
//头文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//原型:
int open(const char *pathname, int flags); //打开已存在的文件
//const char *pathname:硬盘中文件的位置,在下面的例子中----->“./database/1.txt”
//int flags:可以以可读可写的方式打开硬盘中1.txt文件--------->“O_RDWR”
//所以在下面的例子中为:int open(./database/1.txt,O_RDWR)-->打开相应的文件
int open(const char *pathname, int flags, mode_t mode);//创建新文件
//参数介绍:
pathname:表示文件所在的路径,及硬盘中的路径,放入指针中
flags:打开权限
·O_RDONLY:只读
·O_WRONLY:只写
·O_RDWR:可读可写
以上三个是互斥的
========================
·O_CREAT:创建
·O_TRUNC:清空
mode:文件的权限(当新建文件时赋予0777八进制表示,是最高权限)
//返回值:
返回成功:对应的文件描述符(如果成功打开一个文件,那就用一个数字去代表这个文件,从3开始的。范围是0~1023
返回失败:-1
文件描述符:
0---> 标准输入(键盘)
1---> 标准输出(屏幕)
2---> 标准出错(屏幕)
在文件夹的database里面建立文本文件
测试
在下面的代码先对open函数进行熟悉,涉及到文件的打开
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//文件的打开
int main (int argc,char *argv[])
{
int fd_txt=open("./database/1.txt",O_RDWR);
if(-1==fd_txt){
printf("文件打开失败\n");
}
else{
printf("文件打开成功,文件描述符的数值:%d\n",fd_txt);
}
return 0;
}
⭐️ 通过最上面软件设计的步骤:编辑代码、编译程序、下载软件到目标板、仿真调试、系统调试
⭐️ 其中在系统调试调试中执行*./main运行代码时会出现打开文件错误的提示,其原因是我们要写入 的1.txt文档是在database文件夹中,而开发板中是没有database文件夹和1.txt文件的,所以open*执行错误,即提示打开文件失败
⭐️ 因此我们需要执行以下指令
[root@GEC6818 ~]#cd //回到根目录
[root@GEC6818 ~]#mkdir database //创建一个database文件夹
[root@GEC6818 ~]#touch 1.txt //创建1.txt文本文件在database中
[root@GEC6818 ~]#cd… //返回上一级目录,因为要在database外面运行程序
[root@GEC6818 ~]#ls //用ls查看当前目录下的文件:可以看到database、main
[root@GEC6818 ~]# ./main //再进行运行程序,显示打开文件成功,文件描述符为3
write()接口
//功能: 将数据写入指定文件
//头文件:
#include <unistd.h>
//函数原型:
ssize_t write(int fd, void *buf, size_t count);
//参数说明:
//数据存储在哪里?一般使用数组/文本文件1.txt/sqlite3数据库作为数据源头去写入另一个文件
//“张三”---->中文要使用字符串常量存储
//如:char name_information[8]={“张三”};
int fd //将数据写入的文件,即文件描述符,就是open函数返回的数值,即fd_txt
void *buf //使用的是任意指针,即要写入的数据的缓冲区,即数据源name_information
size_t count //想写入到文件的字节数,即使用sizeof(name_information)计算数组的字节数
//返回值:
成功:实际写入的字节数
失败:-1
close()接口 关闭硬盘中的文件
//功能: 关闭文件并释放资源
//头文件:
#include <unistd.h>
//函数原型:
int close(int fd);
//参数说明:
fd:即将要关闭的文件的描述符 //即fd_txt
//返回值:
成功:0 失败:-1
总结上文所讲到的函数接口及程序
功能:往数据库1.txt文件中写入张三用户的姓名
Step1:打开硬盘中的1.txt文件。在ubuntu系统使用open函数打开文件/windows中直接鼠标打开
open函数需要配置参数,要学会指针的调用
Step2:写入张三用户的姓名到1.txt文件中。在ubuntu系统使用write函数写入信息/windows中通过键盘输入信息
Step3:关闭硬盘中的1.txt。在ubuntu系统使用close函数关闭文件/windows中点击关闭的控件关闭文件
其代码如下
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h> //write、close函数的头文件
int main(int argc,char *argv[])
{
//第一步:打开文件并存储文件描述符
int fd_txt=open("./database/1.txt",O_RDWR);
if(-1==fd_txt){
printf("文件打开失败\n");
}
else{
printf("文件打开成功,文件描述符的数值:%d\n",fd_txt);
}
//第二步,在打开的文件中写入字符
char name_information[8]={“张三”};
write(fd_txt,name_information,sizeof(name_information));
//第三步,写完数据后关闭文件
close(fd_txt);
return 0;
}
在上述的step1~step3步骤完成后,即已经向文件里面写入了数据,如何查看数据库database中的1.txt文件的数据呢?就要使用下面的指令,若有数据,就会在终端上显示文件的数据
cat ./database/1.txt
接着我们还可以写入多个信息,就要使用二维数组,再加个循环就好了,代码如下
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h> //write、close函数的头文件
int main(int argc,char *argv[])
{
//第一步:打开文件并存储文件描述符
int fd_txt=open("./database/1.txt",O_RDWR);
if(-1==fd_txt){
printf("文件打开失败\n");
}
else{
printf("文件打开成功,文件描述符的数值:%d\n",fd_txt);
}
//第二步,在打开的文件中写入字符
char name_information[8]={“张三”};
char name_information[8]={“李四”};
char name_information[8]={“王五”};
char name_information[8]={“赵六”};
char name_information[4][8]={
"张三",
"李四",
"王五",
"赵六"
};
int i=0;
for(i=0;i<4;i++){
write(fd_txt,name_information[i],sizeof(name_information));
}
//第三步,写完数据后关闭文件
close(fd_txt);
return 0;
}
//输出
张三李四王五赵六李四王五赵六赵六王五赵六赵六王五赵六赵六王五李四//不知道为什么输出这个?我的就不是。。。
read()接口
//函数功能: 从指定文件中读取数据
//头文件:
#include <unistd.h>
//函数原型:
ssize_t read(int fd, void *buf, size_t count);
//参数说明:
int fd //从文件fd中读取数据
void *buf //指向存放读到的数据的缓冲区
size_t count //想要从文件fd中读取的字节数
//返回值:
成功:实际读到的字节数
失败:-1
lseek()接口
//函数功能:文件指针偏移
//头文件:
#include <sys/types.h>
#include <unistd.h>
//原型:
off_t lseek(int fd, off_t offset, int whence);
//参数:
fd //文件描述符,即要操作哪个文件的光标
offset //偏移量
whence: //基点
SEEK_SET //文件开头
SEEK_CUR //当前位置
SEEK_END //文件末尾
利用文件IO,实现文件的复制
#include<string.h>
#include<string.h>
// ./mycp 1.txt 2.txt
// argv[0] argv[1] argv[2]
int main(int argc,char **argv) //argc是参数个数,argv是参数列表
{
//1.打开源文件
int fd1=open(argv[1],O_RDONLY);
//2.创建目标文件
int fd2=open(argv[2],O_RDONLY|O_CREAT|O_TRUNC);
if(fd1==-1||fd2==-1)
{
perror("open failed");
return -1;
}
char buf[100];
int count;
while(1)
{
bzero(buf,100); //清空数组
count=read(fd1,buf,sizeof(buf)); //从1.txt读出数据
printf("count=%d\n",count);
if(count==0)
break;
write(fd2,buf,strlen(buf)); //将数据写入2.txt
}
close(fd1);
close(fd2);
return 0;
}