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

c语言练习【实现终端功能、dup2实现文件拷贝、read write文件加载到链表】

 练习1:实现终端功能

请实现一个终端的功能,注意需要带有cd功能

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MAX_CMD_LENGTH 1024  // 最大命令长度
#define MAX_ARG_COUNT 64     // 最大参数数量

// 显示提示符,通常是当前工作目录
void print_prompt() {
    char cwd[MAX_CMD_LENGTH];
    if (getcwd(cwd, sizeof(cwd)) != NULL) {
        printf("%s$ ", cwd);
    } else {
        perror("getcwd");
    }
}

// 执行命令
void execute_command(char **args) {
    pid_t pid = fork();
    if (pid == -1) {
        perror("fork");
        return;
    } else if (pid == 0) {  // 子进程执行命令
        if (execvp(args[0], args) == -1) {
            perror("execvp");
        }
        exit(1);  // 如果 execvp 失败,退出子进程
    } else {  // 父进程等待子进程完成
        wait(NULL);
    }
}

// 处理用户输入的命令
void handle_command(char *input) {
    char *args[MAX_ARG_COUNT];
    char *token;
    int i = 0;

    // 去除输入末尾的换行符
    input[strcspn(input, "\n")] = 0;

    // 解析命令和参数
    token = strtok(input, " ");
    while (token != NULL) {
        args[i++] = token;
        token = strtok(NULL, " ");
    }
    args[i] = NULL;

    // 判断是否是 cd 命令
    if (args[0] != NULL && strcmp(args[0], "cd") == 0) {
        if (args[1] == NULL) {
            fprintf(stderr, "cd: missing argument\n");
        } else if (chdir(args[1]) == -1) {
            perror("cd");
        }
    } else if (args[0] != NULL && strcmp(args[0], "exit") == 0) {
        // 退出命令
        exit(0);
    } else {
        // 否则执行其他命令
        execute_command(args);
    }
}

int main() {
    char input[MAX_CMD_LENGTH];

    while (1) {
        print_prompt();  // 打印提示符
        if (fgets(input, sizeof(input), stdin) == NULL) {
            perror("fgets");
            break;
        }

        handle_command(input);  // 处理命令
    }

    return 0;
}

练习2:dup2   fgets   

请使用dup2 + fgets + printf 实现文件拷贝功能

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#define BUFFER_SIZE 1024

// 文件拷贝函数
void copy_file(const char *source, const char *destination) {
    FILE *src_file = fopen(source, "r");
    if (src_file == NULL) {
        perror("Failed to open source file");
        exit(1);
    }

    int dest_fd = open(destination, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (dest_fd == -1) {
        perror("Failed to open destination file");
        fclose(src_file);
        exit(1);
    }

    // 重定向标准输出到目标文件
    if (dup2(dest_fd, STDOUT_FILENO) == -1) {
        perror("dup2 failed");
        fclose(src_file);
        close(dest_fd);
        exit(1);
    }

    char buffer[BUFFER_SIZE];
    while (fgets(buffer, sizeof(buffer), src_file)) {
        // 使用printf输出到标准输出(现在已经被重定向到目标文件)
        printf("%s", buffer);
    }

    fclose(src_file);
    close(dest_fd);
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <source file> <destination file>\n", argv[0]);
        exit(1);
    }

    copy_file(argv[1], argv[2]);
    printf("File copied successfully.\n");

    return 0;
}

练习3:read write 

请使用read 和 write 实现链表保存到文件,以及从文件加载数据到链表中的功能

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#define FILENAME "linked_list.dat"

// 定义链表节点
typedef struct node {
    int data;
    struct node *next;
} node_t;

// 创建新的链表节点
node_t *create_node(int data) {
    node_t *new_node = (node_t *)malloc(sizeof(node_t));
    if (!new_node) {
        perror("malloc");
        exit(1);
    }
    new_node->data = data;
    new_node->next = NULL;
    return new_node;
}

// 将链表保存到文件
void save_list_to_file(node_t *head) {
    int fd = open(FILENAME, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) {
        perror("open");
        exit(1);
    }

    node_t *current = head;
    while (current != NULL) {
        // 写入每个节点的 data
        if (write(fd, &current->data, sizeof(current->data)) == -1) {
            perror("write");
            close(fd);
            exit(1);
        }
        current = current->next;
    }

    close(fd);
}

// 从文件加载链表数据
node_t *load_list_from_file() {
    int fd = open(FILENAME, O_RDONLY);
    if (fd == -1) {
        perror("open");
        return NULL;
    }

    node_t *head = NULL;
    node_t *tail = NULL;

    int data;
    while (read(fd, &data, sizeof(data)) > 0) {
        node_t *new_node = create_node(data);
        if (head == NULL) {
            head = new_node;
            tail = head;
        } else {
            tail->next = new_node;
            tail = tail->next;
        }
    }

    close(fd);
    return head;
}

// 打印链表
void print_list(node_t *head) {
    node_t *current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("NULL\n");
}

// 释放链表内存
void free_list(node_t *head) {
    node_t *current = head;
    while (current != NULL) {
        node_t *temp = current;
        current = current->next;
        free(temp);
    }
}

int main() {
    // 创建一个链表
    node_t *head = create_node(10);
    head->next = create_node(20);
    head->next->next = create_node(30);

    printf("原来的:\n");
    print_list(head);

    // 保存链表到文件
    save_list_to_file(head);

    // 释放原链表
    free_list(head);

    // 从文件加载链表
    node_t *loaded_head = load_list_from_file();

    printf("\n加载后的:\n");
    print_list(loaded_head);

    // 释放加载的链表
    free_list(loaded_head);

    return 0;
}


http://www.kler.cn/a/531958.html

相关文章:

  • 新月军事战略分析系统使用手册
  • 当WebGIS遇到智慧文旅-以长沙市不绕路旅游攻略为例
  • Spark的基本概念
  • 哈夫曼树并查集
  • 智能小区物业管理系统推动数字化转型与提升用户居住体验
  • 网络原理(4)—— 网络层详解
  • IntelliJ IDEA远程开发代理远程服务器端口(免费内网穿透)
  • 图算法概述
  • ZeRO(Zero Redundancy Optimizer) 技术
  • 《Linux服务与安全管理》| 数据库服务器安装和配置
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.18 对象数组:在NumPy中存储Python对象
  • 记录 | 基于MaxKB的文字生成视频
  • Leetcode680:验证回文串 II
  • 物业管理平台系统为社区管理带来数字化转型与服务创新新机遇
  • 高阶开发基础——快速入门C++并发编程5 信号量的使用
  • 自定义数据集 使用paddlepaddle框架实现逻辑回归
  • 农历2025开始 笔记
  • 基于STM32的智能健康监测手环
  • Sqoop导入MySQL中含有回车换行符的数据
  • 【Deep Seek本地化部署】修改模型保存位置
  • (done) MIT6.S081 2023 学习笔记 (Day7: LAB6 Multithreading)
  • 【C++】继承(下)
  • 吴恩达深度学习——卷积神经网络基础
  • GESP2023年12月认证C++六级( 第三部分编程题(1)闯关游戏)
  • PyQt4学习笔记1】使用QWidget创建窗口
  • Kubernetes服务网格实战:从理论到落地