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

 练习1:实现终端功能

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

#include 
#include 
#include 
#include 
#include 
#include 

#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 
#include 
#include 
#include 

#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  \n", argv[0]);
        exit(1);
    }

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

    return 0;
}

练习3:read write 

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

#include 
#include 
#include 
#include 
#include 

#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, ¤t->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;
}

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

你可能感兴趣的:(c语言,链表,开发语言)