显示指定目录下所有.c文件中出现指定字符串的行号 Linux环境 C语言实现

news2024/10/18 5:35:45

问题:显示指定目录及其后代目录下所有.c文件中出现指定字符串的行号 


算法:

分为两个文件编写 :

        display_string_lineno.c  , Read_line.c

分为三个函数编写 :

        void display_lineno(char* dirname,const char *pstr);

        void print_string_line_no(char *path,char *file,const char *pstr);

        char *Read_line(FILE* fp,int *plinelen);


代码:

display_string_lineno.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include <dirent.h>
// 在.c文件中找和打印pstr
void display_lineno(char* dirname,const char *pstr);
// 找出文件夹中的.c文件 并传入display_lineno()函数中
void print_string_line_no(char *path,char *file,const char *pstr);
// 读一整行
char *Read_line(FILE* fp,int *plinelen);

int main(int argc,char* argv[]){
    if(argc < 2){
        printf("The argument is too few\n");
        return 1;
    }

    display_lineno(argv[1],"stdio");

    return 0;
}

void print_string_line_no(char *path,char *file,const char *pstr){
    int len = 0;
    char *pathfile = NULL;
    FILE* fp = NULL;
    char *pline = NULL;
    int lineno = 0;

    len = strlen(path) + strlen(file) + 1 + 1;
    pathfile = (char*)malloc(len); // 动态分配
    if(pathfile == NULL){
        printf("Malloc for %d-char failed\n",len);
        return ;
    }
    memset(pathfile,0,len);
    // 构造递归文件夹的路径信息
    strcpy(pathfile,path);
    strcat(pathfile,"/");
    strcat(pathfile,file);

    fp = fopen(pathfile,"r");
    if(fp == NULL){
        printf("r-open %s failed\n",pathfile);
        return ;
    }

    pline = Read_line(fp,NULL); // 读一整行
    while(pline != NULL){
        lineno++; // 行号+1
        if(strstr(pline,pstr) != NULL)  printf("%s:%d\n",pathfile,lineno); // 找到了就打印输出

        free(pline); // 在读下一行之前free掉空间
        pline = NULL;

        pline = Read_line(fp,NULL); // 继续读下一行
    }

    fclose(fp);
    fp = NULL;
}

void display_lineno(char* dirname,const char *pstr){
    DIR *pd = NULL;
    struct dirent *pitem = NULL;
    int len = 0;
    char* p = NULL;
    char *psubdir = NULL;

    pd = opendir(dirname);

    pitem = readdir(pd);
    while(pitem != NULL){
        if(pitem->d_type == DT_REG){ // 是否为普通文件
            len = strlen(pitem->d_name);
            if(len >= 2){
                p = pitem->d_name + len - 1 - 1;
                if(strcmp(p,".c") == 0) // 判断是否是.c文件
                    print_string_line_no(dirname,pitem->d_name,pstr);
            }
        }
        else if(pitem->d_type == DT_DIR){
            if(strcmp(pitem->d_name,".") != 0 && strcmp(pitem->d_name,"..") != 0){
                len = strlen(dirname) + strlen(pitem->d_name) + 1 + 1;

                psubdir = (char*)malloc(len);// 动态分配
                if(psubdir == NULL){
                    printf("Malloc %d-char failed\n",len);
                    return ;
                }
                memset(psubdir,0,len);
                // 构造递归文件夹的路径信息
                strcpy(psubdir,dirname);
                strcat(psubdir,"/");
                strcat(psubdir,pitem->d_name);

                display_lineno(psubdir,pstr);

                free(psubdir);// 释放空间避免内存泄漏
                psubdir = NULL;
            }
        }
        pitem = readdir(pd);
    }
    closedir(pd);
    pd = NULL;
}

Read_line.c (读一整行)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
char *Read_line(FILE* fp,int *plinelen){
    int curloc = 0;
    int cnt = 0;
    int ret = 0;
    char *pout = NULL;
    // 1.获取位置指示器当前指示位置----起始位置
    curloc = ftell(fp);
    // 2.统计指示器当前指示位置到行尾的字符个数(包括\n)
    ret = fgetc(fp);
    while(ret != '\n' && ret >= 0){
        cnt++;
        ret = fgetc(fp);
    }
    // 3.有效字符的个数(不含行尾标记)填入plinelen指向空间里
    if(plinelen != NULL)    *plinelen = cnt;
    if(cnt <= 0)    return 0;
    if(ret == '\n') cnt++; // 将\n计算在内
 
    // 4.动态分配空间
    cnt++; // 留出最后\0的位置
    pout = (char*)malloc(sizeof(char)*cnt);
    if(pout == NULL){
        printf("Malloc for %d-char failed.\n",cnt);
        return NULL;
    }
    memset(pout,0,cnt);
    // 5.将位置指示器定位到起始位置
    fseek(fp,curloc,0);
    // 6.调用fgets
    fgets(pout,cnt,fp);
    // 7.判断最后一个字符如果是'\n',将其替换成'\0'
    if(*(pout + cnt - 2) == '\n')   *(pout + cnt - 2) = '\0';
    // 8.返回动态空间的地址
    return pout;
}

输出:

省略 gcc 过程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2217558.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sankey.top - 桑基图/桑吉图/流程图/能量流/物料流/能量分析

sankey.top 桑基图大师(SankeyMaster)是您创建复杂桑基图表的首选工具。轻松输入数据并创建桑基图表&#xff0c;准确揭示复杂的数据关系&#xff01; 应用 https://apps.apple.com/cn/app/sankeymaster-sankey-diagram/id6474908221 在线编辑器 https://studio.sankeymaste…

解决ultralytics中的YOLOv8在执行task.py文件添加模块操作出现的KeyError报错

报错详情&#xff1a; 在ultralytics项目文件夹内运行/home/xxx/ultralytics/train.py进行单GPU训练的时候训练可以正常进行 from ultralytics import YOLO# Load a model model YOLO("/home/xxx/ultralytics/ultralytics/cfg/models/v8/yolov8s-FASFF.yaml") # …

Github学生包的JetBrains认证过期/idea认证过期如何解决?

官网通过Github更新状态即可JetBrains Account 注意要到邮箱走流程

自动化测试与敏捷开发的重要性

敏捷开发与自动化测试是现代软件开发中两个至关重要的实践&#xff0c;它们相互补充&#xff0c;共同促进了软件质量和开发效率的提升。 敏捷开发的重要性 敏捷开发是一种以人为核心、迭代、循序渐进的软件开发方法。它强调以下几个核心价值观和原则&#xff1a; 个体和交互…

力扣 简单 83.删除排序链表中的重复元素

文章目录 题目介绍题解 题目介绍 题解 法一&#xff1a;带dummy node class Solution {public ListNode deleteDuplicates(ListNode head) {//根据提示&#xff0c;val的值在-100~100&#xff0c;如果括号里面不填则默认dummy.val0&#xff0c;可能会和某些测试用例的val一样…

第三季度中国游戏市场收入创历史新高;京东物流与淘宝天猫达成合作;YouTube 上线“用相机拍摄”标签....|网易数智日报

第三季度中国游戏市场收入917.66亿&#xff0c;创历史新高 中国音数协游戏工委今日发布了最新的 2024 年第三季度中国游戏产业季度报告。 数据显示&#xff0c;2024 年第三季度中国游戏市场收入 917.66 亿元&#xff0c;环比增长 22.96%&#xff0c;同比增长 8.95%。 中国音…

完全指南:如何高效进行业务应用开发?

❤️ 温馨提醒 本篇文章较长&#xff0c;你可以根据目录选择最感兴趣的部分阅读。当然&#xff0c;我相信如果你全部阅读完&#xff0c;一定会有不少的收获。 引言 企业对业务应用开发的需求正在日益增长。 据 Gartner 统计&#xff0c;全球企业软件市场预计将在 2025 年达到…

数据结构——哈夫曼树及其应用(哈夫曼编码)

判断树&#xff1a;用来描述分类过程的二叉树 哈夫曼树&#xff08;最优二叉树&#xff09;的基本概念 路径&#xff1a;从树中一个结点到另一个结点之间的分支构成这两个结点间的路径。 结点的路径长度&#xff1a;两结点间路径上的分支数。 结点的路径长度计算&#xff1…

【jQuery】jQuery 处理 Ajax 以及解决跨域问题的方式

文章目录 HTTP原生创建 AjaxjQuery 处理 Ajax$.ajax()$().load()$.get()$.post() 跨域CORSJSONPiframeweb sockets HTTP 超文本传输协议&#xff08;HTTP&#xff0c;HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。设计 HTTP 最初的目的是为了提供一种发…

Redis中String类型数据扩容原理分析

大家好&#xff0c;我是 V 哥。在 Java 中&#xff0c;我们有动态数组ArrayList&#xff0c;当插入新元素空间不足时&#xff0c;会进行扩容&#xff0c;好奇 Redis 中的 String 类型&#xff0c;C 语言又是怎样的实现策略&#xff0c;带着疑问&#xff0c;咱们来了解一下。 最…

集成电路公司进销存系统生成合同——未来之窗行业应用跨平台架构

一、进销存生成合同优势 1. 提高效率&#xff1a;节省了手动起草和编辑合同的时间&#xff0c;能够快速生成合同&#xff0c;加快业务流程。 2. 减少错误&#xff1a;避免了人工输入可能导致的拼写、数据错误等&#xff0c;提高合同的准确性和规范性。 3. 数据一致性&#xff…

Python Web服务器网关接口

gunicorn 是 WSGI。 因其中一个项目说是要用 gunicorn &#xff0c;然后就顺便了解下 gunicorn 这个东西是干什么的。 要想了解 gunicorn &#xff0c;那么就需要知道 WSGI 是什么东西。 开始都不知道 WSGI 是什么概念&#xff0c;还以为是个新东西。 其实就是 Python 实现…

通过Caffeine实现JVM进程缓存、配置OpenResty完成nginx的本地缓存和redis操作,Canal实现缓存同步——配置多级缓存,一篇足矣

目录 JVM缓存&#xff08;本地进程缓存&#xff09;Caffeine技术栈基础介绍&#xff1a; OpenResty技术栈基础介绍 Canal技术栈介绍 一、通过Caffeine实现进程缓存 1.1首先需要为你需要的数据构建Cache缓存对象&#xff0c;为了方便使用&#xff0c;可以将其声明为一个bea…

Android 13.0 Launcher3定制之首页时钟小部件字体大小修改

1.前言 在13.0的系统rom产品开发中,在一些Launcher3的定制化开发中,在对于一些小屏幕的产品开发中,在首页添加时钟小部件会显得字体有点小, 所以为了整体布局美观就需要改动小部件的布局日期字体的大小来实现整体的布局美观效果,接下来来具体实现相关的功能 具体效果图: …

linux 修改主机名和用户名颜色

编译 ~/.bashrc vim ~/.bashrc 如下格式 PS1\[\e[1;31m\]\h:\[\e[0;32m\]\w \[\e[1;34m\]\u\[\e[0m\]\$ 颜色随自己喜好修改 如下使其生效 source ~/.bashrc 效果如下 Enjoy&#xff01;&#xff01;&#xff01;

数学考研错题本:查漏补缺,高效提升备考策略

考研之路漫长而艰辛&#xff0c;对于数学这一学科来说&#xff0c;错题本的建立与利用显得尤为重要&#xff0c;通过分析错题&#xff0c;我们可以查漏补缺&#xff0c;找到自己的薄弱环节&#xff0c;从而有针对性地进行复习&#xff0c;本文将详细阐述如何建立和利用数学考研…

【数据采集工具】Sqoop从入门到面试学习总结

国科大学习生活&#xff08;期末复习资料、课程大作业解析、大厂实习经验心得等&#xff09;: 文章专栏&#xff08;点击跳转&#xff09; 大数据开发学习文档&#xff08;分布式文件系统的实现&#xff0c;大数据生态圈学习文档等&#xff09;: 文章专栏&#xff08;点击跳转&…

数控机械制造工厂ERP适用范围有哪些

在当今制造业高速发展的背景下&#xff0c;企业资源计划(ERP)系统已成为提升工厂管理效率、实现生产自动化与信息化的关键工具。特别是对于数控机械制造工厂而言&#xff0c;一个合适的ERP系统能够帮助其优化生产流程、提高产品质量、降低生产成本并增强市场竞争力。 1. 生产计…

React 项目热更新失效问题的解决方案和产生的原因

背景和意义 在修复React项目热更新失效的问题时&#xff0c;经过一系列问题排查和依赖升级&#xff0c;最终成功修复了问题并为后续开发规避了类似的问题。 依赖升级 Vite版本升级 原React项目Vite版本升级到^4.4.5 Vite 4 在构建和开发服务器的性能上进行了优化&#xff…

Java--集合之vectorlinkedlisthashset结构

文章目录 0.架构图1.vector解析2.LinkedList分析2.1源码分析2.2迭代器遍历的三种方式 3.set接口的使用方法3.1基本使用说明3.2基本遍历方式3.3HashSet引入3.4数组链表模拟3.5hashset扩容机制3.6hashset源码解读3.7扩容*转成红黑树机制**我的理解 0.架构图 1.vector解析 和之前介…