当前位置: 首页 > news >正文

从0开始学linux韦东山教程第四章问题小结(2)

  本人从0开始学习linux,使用的是韦东山的教程,在跟着课程学习的情况下的所遇到的问题的总结,理论虽枯燥但是是基础。说实在的越看视频越感觉他讲的有点乱后续将以他的新版PDF手册为中心,视频作为辅助理解的工具。参考手册为嵌入式Linux应用开发完全手册V5.3_IMX6ULL_Pro开发板。
摘要:这节课手册上没有全部内容,我是根据他的补充视频制作的这个总结博客。这节博客主要讲的是,文本特性设置,以及怎么用vs code调试去逐行理解代码,明白其工作原理。
摘要关键词:文本特性设置、vs code调试

本文详细介绍以下问题,如果你遇到了以下问题,看看我的方案能否解决。

1.文本特性设置
2.怎么用vs code调试去逐行理解代码,明白其工作原理

1.文本特性设置

斜杠加名词是经常用于内容查找的

/mode //查找
ls -l

在这里插入图片描述
    ls -l 命令用于在类 Unix 系统(如 Linux 和 macOS)中列出当前目录下文件和子目录的详细信息。具体来说,-l 是一个选项,表示以长格式显示文件或目录的详细信息。

如图所示可以看出不同的文件的不同权限。
在这里插入图片描述
在这里插入图片描述
如图所示当设置权限为0711时,

0111001001rwx;  --x ; --x

对应的权限如下图所示。
在这里插入图片描述

2.怎么用vs code调试去逐行理解代码,明白其工作原理

综合实验部分

05_process_excel

    进入此部分的时候,本人在思考,编写一个实验程序,不可能像老师一样,一步就编写成功,更多的时候是一点点调试,所以我的重心就是搞懂代码并且调试代码。调试代码使用的是VS code。
调试别人代码的时候,先测试通过一下。

./process_excel score.csv progress.csv

在这里插入图片描述
输入csv的格式
在这里插入图片描述
输出csv的格式
在这里插入图片描述
    看到输入的格式了,但是如何实现分行,就得知道最后一个标志位回车换行符。
从ubuntu中打开输入,以下命令符。

cd 05_process_excel
hexdump -C score.csv
cat score.csv

在这里插入图片描述)
cd 05_process_excel:打开文件夹
hexdump -C score.csv:查看文件内容的十六进制
cat score.csv:查看源文件的内容

0d 0a也就是回车、换行。

/* 返回值: n表示读到了一行数据的数据个数(n >= 0)*         -1(读到文件尾部或者出错)*/
static int read_line(int fd, unsigned char *buf)
{/* 循环读入一个字符 *//* 如何判断已经读完一行? 读到0x0d, 0x0a */unsigned char c;int len;int i = 0;int err = 0;while (1){len = read(fd, &c, 1);if (len <= 0){err = -1;break;}else{if (c != '\n' && c != '\r'){buf[i] = c;i++;}else{/* 碰到回车换行   */err = 0;break;}}}buf[i] = '\0';if (err && (i == 0)){/* 读到文件尾部了并且一个数据都没有读进来 */return -1;}else{return i;}
}

这个函数的作用是读取行,首先while(1)死循环读取输入文件fd的内容。逐字读取,

在这里插入图片描述

保存的时候使用绝对地址,不然就保存到这去了
在这里插入图片描述
在这里插入图片描述
    本人也是第一次用VS code调试,发现len等一系列变量是一长串数字,后来才知道这只是初始赋值的地址,真正的内容还没有给。

开始调试

为什么使用 char *argv[3];
argv[0]= “./process_excel” ;
argv[1]= “D:/Linux/project/05_process_excel/score.csv” ;
argv[2]=“D:/Linux/project/05_process_excel/progress.csv”;可以接受变量,
但是而不用char argv[3];

char * argv[3]: 这里 argv 是一个 数组,包含 3 个指向 char 的指针(即 char* 类型)。每个 argv[i] 都是一个指向字符串的指针,可以指向字符串常量或者其他字符数组。例如,argv[0] 可以指向字符串 “./process_excel”,argv[1] 可以指向字符串 “D:/Linux/project/05_process_excel/score.csv” 等。

char argv[3]:这里,argv 是一个 字符数组,它只存储 3 个字符,并不是指针。你声明了一个大小为 3 的字符数组,但是每个数组元素都是一个字符类型 (char),而不是一个指向字符串的指针 (char*)。当你写 argv[0] = “./process_excel”; 时,编译器试图将字符串 ./process_excel 赋值给 argv[0],但是 argv[0] 只能存储一个字符,而不是一个指针。所以这会引起编译错误。 也就是他只会存储 '.' 、 '/' 、 'p'

在这里插入图片描述
而char * 则会根据需要自动调节地址长度。

在这里插入图片描述
    当我执行完这一行后发现,fd_data等于3,打开"D:/Linux/project/ 05_process_excel/score.csv"文件地址后,输出为3。文件成功打开,fd_data 存储了一个指向该文件的描述符,值为 3,可以用于后续的文件操作(如读取、关闭等)。

fd_result = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0644);

O_RDWR:表示以读写模式打开文件。如果文件存在,既可以读取文件内容,也可以向文件写入数据。

O_CREAT:表示如果文件不存在,则创建文件。

O_TRUNC:表示如果文件已经存在,并且打开模式为写入模式,那么打开文件后会截断文件的内容,使其长度为 0,相当于清空文件

0644:这是文件权限位,表示创建的文件的权限:

6(二进制 110)表示文件所有者有读和写的权限(rw-)。
4(二进制 100)表示文件所属的用户组有读的权限(r–)。
4(二进制 100)表示其他用户有读的权限(r–)。

len = read(fd, &c, 1);

&c:这是一个指向变量 c 的指针,表示读取的数据将存储到 c 变量中。c 是一个字符变量(如 char c),那么读取的数据会存入 c。

1:表示读取的字节数。在这个例子中,1 表示每次调用 read() 时,最多读取一个字节的数据。

c为239,也就是十六进制的0XEF。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
对应的也就是第一个变量。以此类推读取完整行之后。如果c != ‘\n’ 且 c != '\r’不成立,则跳出循环将0x0d换成\0。
然后进入以下函数。

process_data(unsigned char *data_buf, unsigned char *result_buf)

关键可能是这几个函数不是那么明白。

strcpy(result_buf, data_buf);
sscanf(data_buf, "%[^,],%d,%d,%d,", name, &scores[0], &scores[1], &scores[2]);
sprintf(result_buf, "%s,%d,%d,%d,%d,%s", name, scores[0], scores[1], scores[2], sum, levels[level]);

strcpy(result_buf, data_buf):strcpy 是标准库函数,它将源字符串(data_buf)复制到目标字符串(result_buf)中,直到遇到空字符 \0。这会直接覆盖 result_buf 中的原有内容。

sscanf(data_buf, “%[^,],%d,%d,%d,”, name, &scores[0], &scores[1], &scores[2]):从 data_buf 中读取并解析数据,格式化为指定的变量。这行代码将 data_buf 中的名字、三个整数分数提取出来,分别存储在 name 和 scores 数组中
在这里插入图片描述)
其实可以看到data_buf也就这4个变量。

sprintf(result_buf, “%s,%d,%d,%d,%d,%s”, name, scores[0], scores[1], scores[2], sum, levels[level]):是标准库函数,用于将格式化的数据输出到字符串中,而不是打印到标准输出。

  if (len != 0){/* 处理数据 */process_data(data_buf, result_buf);/* 写入结果文件 *///write_data(fd_result, result_buf);write(fd_result, result_buf, strlen(result_buf));write(fd_result, "\r\n", 2);}

最后逐行将文本信息写到fd_result中。

    其实到这主体流程也就明白了,但是你有没有思考过一个问题,我从头到尾只看到了len在加加,它是怎么做到第一行打印完后接着打印第二行的,理论上它打印完第一行后会接着打印第一行,因为没有累加操作。
    其实是因为len = read(fd, &c, 1); 这行代码的作用是从文件描述符 fd 中读取一个字节,并将其存储到变量 c 中。如果你担心的是之前已经读取的内容会被重复读取,通常不需要担心,因为 read 函数每次都会从当前位置继续读取,而不会回退到之前读取过的位置。

    具体来说,操作系统会跟踪文件的当前位置,每次调用 read 时,它会自动更新文件指针。所以,除非你手动操作文件指针(例如通过 lseek 等操作),每次 read 都会从上次读取后的位置继续读取。
也没人跟我说过这个函数还有这个用处啊。

相关文章:

  • Java虚拟机 -虚拟机栈
  • GUI实验
  • 漏洞修复的两种核心方法
  • day25- 系统编程之 标准IO(II) 及 文件IO
  • MCP-1:MCP组件与工作流程
  • 【leetcode】75.颜色分类
  • 一命通关单调栈
  • Vue.js教学第九章:Vue动态与异步组件,高效开发全攻略
  • Speexx: Online Language Training Business Coaching Platform
  • 在 Windows 系统部署对冲基金分析工具 ai-hedge-fund 的笔记
  • Python爬虫实战:获取天气网最近一周北京的天气数据,为日常出行做参考
  • MYSQL日志与事件
  • 【OCCT+ImGUI系列】009-Geom2d-Geom2d_AxisPlacement
  • leetcode2844. 生成特殊数字的最少操作-medium
  • vue页面实现table动态拆分列功能
  • MyBatis:简化数据库操作的持久层框架
  • 什么是endpoints?
  • 江科大TIM定时器hal库实现
  • Python训练Day30
  • 用python实现汉字转拼音工具
  • WordPress快速添加图片/windows优化大师和360哪个好
  • 环艺毕业设计代做网站/全网最全搜索引擎app
  • 织梦中英文网站源码/网站免费网站免费优化优化
  • 中国神鹰网站建设/怎么推广网站链接
  • 手机销售网站设计/app拉新推广平台有哪些
  • 百度网盘做自已网站/北京网站seo招聘