当前位置: 首页 > 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 都会从上次读取后的位置继续读取。
也没人跟我说过这个函数还有这个用处啊。

http://www.xdnf.cn/news/577693.html

相关文章:

  • Java异步编程利器:CompletableFuture 深度解析与实战
  • 【C++ Primer 学习札记】函数传参问题
  • 轻量级高性能Rust HTTP服务器库Hyperlane,助力现代网络服务开发
  • C++:vector容器
  • 心知天气 API 获取天气预报 2025/5/21
  • QML定时器Timer和线程任务WorkerScript
  • 大模型评测与可解释性
  • Day 27 训练
  • Linux中的文件介绍
  • 通过美图秀秀将多张图片合并
  • 【UEFI实战】BIOS编译过程中报错“无法解析的外部符号memcpy”
  • 七: NumPy的使用
  • vue+srpingboot实现多文件导出
  • Unity中GPU Instancing使用整理
  • Python训练Day30
  • 第3周作业-1层隐藏层的神经网络分类二维数据
  • MQTT报文介绍
  • Linux内存分页管理详解
  • Jsoup解析商品信息具体怎么写?
  • 阿里发布扩散模型Wan VACE,全面支持生图、生视频、图像编辑,适配低显存~
  • FreeCAD傻瓜教程-外螺纹的绘制,利用两个实体进行布尔运算来实现
  • 《P1433 吃奶酪》
  • MCU开发学习记录19* - CAN学习与实践(HAL库) - 定时传输、触发传输和请求传输(轮询与中断实现) -STM32CubeMX
  • Python 代码缩进与结构化编程:从基础到风格规范
  • Robotaxi新消息密集释放,量产元年来临谁在领跑?
  • [Java恶补day2] 49. 字母异位词分组
  • 【SW】从3D模型导出dxf图纸
  • 【算法专题十五】BFS解决最短路问题
  • 04_Prometheus监控docker容器(4)
  • 智慧社区新防线:华奥系AI技术如何让夏季安防“零隐患”