当前位置:首页 > 技术 > 正文内容

C语言核心知识:条件编译、文件IO操作与客户信息管理系统实战

访客 技术 2026年7月17日 1

第15章 预处理指令详解

15.1 条件编译指令

条件编译允许程序在编译阶段根据特定条件选择性地编译代码块,这与运行时的if-else语句类似,但工作在编译时期。

1. #if 指令

用于预处理器的条件判断,满足条件时内部的代码行会被编译,否则被编译器忽略。

单分支结构:
#if 条件表达式
    // 代码块
#endif

双分支结构:
#if 条件表达式
    // 条件为真时执行的代码
#else
    // 条件为假时执行的代码
#endif

多分支结构:
#if 条件表达式1
    // 条件1为真时执行的代码
#elif 条件表达式2
    // 条件2为真时执行的代码
#elif 条件表达式3
    // 条件3为真时执行的代码
#else
    // 所有条件都为假时执行的代码
#endif

2. #ifdef 指令

用于判断某个宏是否已经被定义过。

单分支结构:
#ifdef 宏名称
    // 宏已定义时执行的代码
#endif

双分支结构:
#ifdef 宏名称
    // 宏已定义时执行的代码
#else
    // 宏未定义时执行的代码
#endif

3. #if defined 指令

功能与#ifdef类似,但支持同时检查多个宏定义。

#if defined(宏名称1) || defined(宏名称2)
    // 至少一个宏已定义时执行的代码
#endif

4. #ifndef 指令

用于判断某个宏是否未被定义,常用于防止头文件重复包含。

#ifndef 头文件名大写_H
#define 头文件名大写_H
    // 头文件内容
#endif

预处理指令汇总

指令功能说明
#include包含其他源代码文件
#define定义宏或常量
#undef取消已定义的宏
#if条件为真时编译后续代码
#ifdef宏已定义时编译后续代码
#ifndef宏未定义时编译后续代码
#elif前序条件不满足且当前条件满足时编译
#endif结束条件编译块

第16章 输入输出与文件操作

16.1 流的概念

输入流(Input Stream):数据从外部设备(如文件、键盘)传输到程序内存的通道。

输出流(Output Stream):数据从程序内存传输到外部设备(如文件、屏幕)的通道。

16.2 标准输入输出函数

输入函数

  • scanf():格式化输入函数,支持多种数据类型
  • getchar():从标准输入读取单个字符
    函数原型:int getchar(void)
    返回读取字符的ASCII码值
  • gets():读取一行字符串(已不推荐使用)
    注意:该函数存在安全风险,建议使用fgets()替代

输出函数

  • printf():格式化输出函数
  • putchar():输出单个字符到标准输出
    函数原型:int putchar(int character)
  • puts():输出字符串并自动换行
    函数原型:int puts(const char *str)

16.3 文件操作

标准文件指针

文件指针对应设备
stdin键盘(标准输入)
stdout屏幕(标准输出)
stderr屏幕(标准错误)

文件打开与关闭

fopen()函数:
FILE *fopen(const char *filename, const char *mode);
参数:
  filename - 要打开的文件名(可包含路径)
  mode - 打开模式
返回值:成功返回文件指针,失败返回NULL

fclose()函数:
int fclose(FILE *stream);
返回值:成功返回0,失败返回EOF

文件打开模式:

r只读,文件不存在则失败
w只写,文件不存在则创建,存在则清空
a追加写,文件不存在则创建
r+读写,文件必须存在
w+读写,文件不存在则创建,存在则清空
a+读写,文件不存在则创建

文件读取函数

fscanf() - 格式化读取:
int fscanf(FILE *stream, const char *format, ...);
从文件流中按格式读取数据

fgets() - 行读取(推荐使用):
char *fgets(char *str, int num, FILE *stream);
读取一行或指定长度,保留换行符

fgetc() - 字符读取:
int fgetc(FILE *stream);
每次读取一个字符

文件写入函数

fprintf() - 格式化写入:
int fprintf(FILE *stream, const char *format, ...);

fputs() - 字符串写入:
int fputs(const char *str, FILE *stream);

fputc() - 字符写入:
int fputc(int character, FILE *stream);

第17章 客户信息管理系统项目

17.1 项目结构设计

本项目实现一个完整的客户信息管理系统的核心功能,包括菜单显示、客户添加、列表查看、客户删除等操作。

17.1.1 主菜单与程序框架

#include <stdio.h>

// 定义客户信息结构体
typedef struct {
    int id;            // 客户编号
    char name[20];     // 客户姓名
    enum {
        MALE = 'm',
        FEMALE = 'f'
    } gender;          // 客户性别
    int age;           // 客户年龄
    char phone[11];    // 联系电话
    char email[40];    // 电子邮箱
} Client;

// 客户数据存储数组
Client clients[100];
int clientCount = 0;

int main() {
    int running = 1;
    
    while (running) {
        printf("\n========== 客户信息管理系统 ==========");
        printf("\n           1. 添加客户");
        printf("\n           2. 删除客户");
        printf("\n           3. 修改客户");
        printf("\n           4. 客户列表");
        printf("\n           5. 退出系统");
        printf("\n           请选择(1-5): ");
        
        int choice;
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                printf("添加客户功能");
                break;
            case 2:
                printf("删除客户功能");
                break;
            case 3:
                printf("修改客户功能");
                break;
            case 4:
                printf("客户列表功能");
                break;
            case 5: {
                char confirm;
                printf("确定要退出系统吗(Y/N): ");
                getchar();
                scanf("%c", &confirm);
                if (confirm == 'Y' || confirm == 'y') {
                    printf("感谢使用,再见!\n");
                    running = 0;
                }
                break;
            }
            default:
                printf("输入选项无效,请重新选择!");
                break;
        }
    }
    return 0;
}

17.1.2 添加客户功能实现

#include <stdio.h>

typedef struct {
    int id;
    char name[20];
    enum { MALE = 'm', FEMALE = 'f' } gender;
    int age;
    char phone[11];
    char email[40];
} Client;

Client clients[100];
int clientCount = 0;

// 添加客户函数
void addClient() {
    printf("\n========== 添加客户 ==========");
    
    clients[clientCount].id = clientCount + 1;
    
    printf("\n请输入姓名: ");
    scanf("%s", clients[clientCount].name);
    
    printf("请输入性别(m/f): ");
    getchar();
    scanf("%c", (char *)&clients[clientCount].gender);
    
    printf("请输入年龄: ");
    scanf("%d", &clients[clientCount].age);
    
    printf("请输入电话: ");
    scanf("%s", clients[clientCount].phone);
    
    printf("请输入邮箱: ");
    scanf("%s", clients[clientCount].email);
    
    clientCount++;
    printf("\n客户添加成功!");
}

int main() {
    int running = 1;
    
    while (running) {
        printf("\n========== 客户信息管理系统 ==========");
        printf("\n           1. 添加客户");
        printf("\n           2. 删除客户");
        printf("\n           3. 修改客户");
        printf("\n           4. 客户列表");
        printf("\n           5. 退出系统");
        printf("\n           请选择(1-5): ");
        
        int choice;
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                addClient();
                break;
            case 2:
                printf("删除客户功能");
                break;
            case 3:
                printf("修改客户功能");
                break;
            case 4:
                printf("客户列表功能");
                break;
            case 5: {
                char confirm;
                printf("确定要退出系统吗(Y/N): ");
                getchar();
                scanf("%c", &confirm);
                if (confirm == 'Y' || confirm == 'y') {
                    printf("感谢使用,再见!\n");
                    running = 0;
                }
                break;
            }
            default:
                printf("输入选项无效,请重新选择!");
                break;
        }
    }
    return 0;
}

17.1.3 客户列表功能

#include <stdio.h>

typedef struct {
    int id;
    char name[20];
    enum { MALE = 'm', FEMALE = 'f' } gender;
    int age;
    char phone[11];
    char email[40];
} Client;

Client clients[100];
int clientCount = 0;

void addClient() {
    printf("\n========== 添加客户 ==========");
    clients[clientCount].id = clientCount + 1;
    
    printf("\n请输入姓名: ");
    scanf("%s", clients[clientCount].name);
    
    printf("请输入性别(m/f): ");
    getchar();
    scanf("%c", (char *)&clients[clientCount].gender);
    
    printf("请输入年龄: ");
    scanf("%d", &clients[clientCount].age);
    
    printf("请输入电话: ");
    scanf("%s", clients[clientCount].phone);
    
    printf("请输入邮箱: ");
    scanf("%s", clients[clientCount].email);
    
    clientCount++;
    printf("\n客户添加成功!");
}

// 显示客户列表函数
void showList() {
    printf("\n========== 客户列表 ==========");
    
    if (clientCount == 0) {
        printf("\n暂无客户信息,请先添加!");
        return;
    }
    
    printf("\n编号\t姓名\t性别\t年龄\t电话\t邮箱");
    for (int i = 0; i < clientCount; i++) {
        printf("\n%d\t%s\t%c\t%d\t%s\t%s", 
               clients[i].id, 
               clients[i].name, 
               clients[i].gender, 
               clients[i].age, 
               clients[i].phone, 
               clients[i].email);
    }
}

int main() {
    int running = 1;
    
    while (running) {
        printf("\n========== 客户信息管理系统 ==========");
        printf("\n           1. 添加客户");
        printf("\n           2. 删除客户");
        printf("\n           3. 修改客户");
        printf("\n           4. 客户列表");
        printf("\n           5. 退出系统");
        printf("\n           请选择(1-5): ");
        
        int choice;
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                addClient();
                break;
            case 2:
                printf("删除客户功能");
                break;
            case 3:
                printf("修改客户功能");
                break;
            case 4:
                showList();
                break;
            case 5: {
                char confirm;
                printf("确定要退出系统吗(Y/N): ");
                getchar();
                scanf("%c", &confirm);
                if (confirm == 'Y' || confirm == 'y') {
                    printf("感谢使用,再见!\n");
                    running = 0;
                }
                break;
            }
            default:
                printf("输入选项无效,请重新选择!");
                break;
        }
    }
    return 0;
}

17.1.4 删除客户功能

#include <stdio.h>
#include <stdbool.h>

typedef struct {
    int id;
    char name[20];
    enum { MALE = 'm', FEMALE = 'f' } gender;
    int age;
    char phone[11];
    char email[40];
} Client;

Client clients[100];
int clientCount = 0;

void addClient() {
    printf("\n========== 添加客户 ==========");
    clients[clientCount].id = clientCount + 1;
    
    printf("\n请输入姓名: ");
    scanf("%s", clients[clientCount].name);
    
    printf("请输入性别(m/f): ");
    getchar();
    scanf("%c", (char *)&clients[clientCount].gender);
    
    printf("请输入年龄: ");
    scanf("%d", &clients[clientCount].age);
    
    printf("请输入电话: ");
    scanf("%s", clients[clientCount].phone);
    
    printf("请输入邮箱: ");
    scanf("%s", clients[clientCount].email);
    
    clientCount++;
    printf("\n客户添加成功!");
}

void showList() {
    printf("\n========== 客户列表 ==========");
    
    if (clientCount == 0) {
        printf("\n暂无客户信息,请先添加!");
        return;
    }
    
    printf("\n编号\t姓名\t性别\t年龄\t电话\t邮箱");
    for (int i = 0; i < clientCount; i++) {
        printf("\n%d\t%s\t%c\t%d\t%s\t%s", 
               clients[i].id, 
               clients[i].name, 
               clients[i].gender, 
               clients[i].age, 
               clients[i].phone, 
               clients[i].email);
    }
}

// 执行删除操作
bool removeClient(int targetId) {
    if (targetId < 1 || targetId > clientCount) {
        return false;
    }
    
    int index = targetId - 1;
    
    // 将后续客户数据前移
    for (int i = index; i < clientCount - 1; i++) {
        clients[i] = clients[i + 1];
        clients[i].id--;
    }
    
    clientCount--;
    return true;
}

// 删除界面处理
void deleteView() {
    int deleteId;
    printf("\n请输入要删除的客户编号(-1取消): ");
    scanf("%d", &deleteId);
    
    if (deleteId == -1) {
        printf("\n已取消删除操作");
        return;
    }
    
    char confirm;
    printf("确认删除该客户吗(Y/N): ");
    getchar();
    scanf("%c", &confirm);
    
    if (confirm != 'Y' && confirm != 'y') {
        printf("\n已取消删除操作");
        return;
    }
    
    if (removeClient(deleteId)) {
        printf("\n删除成功!");
    } else {
        printf("\n删除失败:该客户不存在!");
    }
}

int main() {
    int running = 1;
    
    while (running) {
        printf("\n========== 客户信息管理系统 ==========");
        printf("\n           1. 添加客户");
        printf("\n           2. 删除客户");
        printf("\n           3. 修改客户");
        printf("\n           4. 客户列表");
        printf("\n           5. 退出系统");
        printf("\n           请选择(1-5): ");
        
        int choice;
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                addClient();
                break;
            case 2:
                deleteView();
                break;
            case 3:
                printf("修改客户功能");
                break;
            case 4:
                showList();
                break;
            case 5: {
                char confirm;
                printf("确定要退出系统吗(Y/N): ");
                getchar();
                scanf("%c", &confirm);
                if (confirm == 'Y' || confirm == 'y') {
                    printf("感谢使用,再见!\n");
                    running = 0;
                }
                break;
            }
            default:
                printf("输入选项无效,请重新选择!");
                break;
        }
    }
    return 0;
}

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。