C12节:练习和作业

本文提供三个C语言编程练习实例:实现贪吃蛇游戏、管理个人信息系统及查询功能,通过这些练习帮助读者掌握结构体和文件操作等核心概念。

1 贪吃蛇练习

/*
    贪吃蛇练习
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define     SIZE             4
enum {UP, DOWN, LEFT, RIGHT};
typedef struct {
    int x;
    int y;
} position;
void show_snake(position *p_position, int size) {
    int pos = 0;
    for (pos = 0;pos <= size - 1;pos++) {
        printf("(%d,%d) ", p_position[pos].x, p_position[pos].y);
    }
    printf("\n");
}
int main() {
    int pos = 0, direction = 0;
    position snake[SIZE], head;
    srand(time(0));
    snake[0].x = rand() % 10;
    snake[0].y = rand() % 10;
    for (pos = 1;pos <= SIZE - 1;pos++) {
        snake[pos] = snake[pos - 1];
        snake[pos].x++;
    }
    show_snake(snake, SIZE);
    while (1) {
        printf("请输入方向(%d代表上,%d代表下,%d代表左,%d代表右):", UP, DOWN, LEFT, RIGHT);
        scanf("%d", &direction);
        head = snake[0];
        switch(direction) {
        case UP:
            head.y--;
            break;
        case DOWN:
            head.y++;
            break;
        case LEFT:
            head.x--;
            break;
        case RIGHT:
            head.x++;
            break;
        }
        for (pos = 0;pos <= SIZE - 1;pos++) {
            if (head.x == snake[pos].x &&
                head.y == snake[pos].y) {
                break;
            }
        }
        if (pos <= SIZE - 1) {
            printf("方向错误\n");
        }
        else {
            for (pos = SIZE - 2;pos >= 0;pos--) {
                snake[pos + 1] = snake[pos];
            }
            snake[0] = head;
            show_snake(snake, SIZE);
        }
    }
    return 0;
}



2   --1.从键盘得到日程信息并最终输出。
       每个日程包含小时数(0--23)和内容两部分
       不要求排序
    --2.对结果进行排序

/*
    结构体练习
*/
#include <stdio.h>
#include <string.h>
struct month {
    char name[10];
    int days;
};
int main() {
    struct month months[12];
    char * names[] =   {"Jan", "Feb", "Mar",
                        "Apr", "May", "Jun",
                        "Jul", "Aug", "Sep",
                        "Oct", "Nov", "Dec"};
    int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int loop = 0;
    for (loop = 0;loop <= 11;loop++) {
        strcpy(months[loop].name, names[loop]);
        months[loop].days = days[loop];
    }
    for (loop = 0;loop <= 11;loop++) {
        printf("名称是%s,天数是%d\n", months[loop].name, months[loop].days);
    }
    return 0;
}
/*
    结构体初始化练习
*/
#include <stdio.h>
/*struct month {
    char name[10];
    int days;
};
typedef struct month month;*/
typedef struct /*month*/ {
    char name[10];
    int days;
} month;
int main() {
    month months[3] = {{"Jan", 31},
                              {"Feb", 28},
                              {"Mar", 31}};
    int loop = 0;
    for (loop = 0;loop <= 2;loop++) {
        printf("名称是%s,天数是%d\n", months[loop].name, months[loop].days);
    }
    return 0;
}



3 编写一个函数录入多个人员信息。每次录入之前都向用户询问。

/*
    人员信息管理系统练习
*/
#include <stdio.h>
#include <string.h>
int save() {
    int num = 0, ids[10] = {}, id = 0, pos = 0;
    char name[20] = {}, buf[20] = {};
    float salary = 0.0f;
    FILE *p_file = fopen("a.bin", "ab");
    if (!p_file) {
        printf("文件打开失败\n");
        return 0;
    }
    while (1) {
        printf("请输入人员id:");
        scanf("%d", &id);
        scanf("%*[^\n]");
        scanf("%*c");
        for (pos = 0;pos <= num - 1;pos++) {
            if (id == ids[pos]) {
                break;
            }
        }
        if (pos <= num - 1) {
            continue;
        }
        printf("请输入人员姓名:");
        fgets(name, 20, stdin);
        if (strlen(name) == 19 && name[18] != '\n') {
            scanf("%*[^\n]");
            scanf("%*c");
        }
        printf("请输入人员工资:");
        scanf("%g", &salary);
        scanf("%*[^\n]");
        scanf("%*c");
        fwrite(&id, sizeof(int), 1, p_file);
        fwrite(name, sizeof(char), 20, p_file);
        fwrite(&salary, sizeof(float), 1, p_file);
        ids[num] = id;
        num++;
        printf("是否要录入下一个员工信息:");
        fgets(buf, 20, stdin);
        if (strlen(buf) == 19 && buf[18] != '\n') {
            scanf("%*[^\n]");
            scanf("%*c");
        }
        if (buf[0] != 'y' && buf[0] != 'Y') {
            break;
        }
    }
    fclose(p_file);
    return num;
}
int main() {
    printf("共录入了%d个用户的信息\n", save());
    return 0;
}

4 编写函数完成基于id的查询功能

/*
    id比较练习
*/
#include <stdio.h>
int main() {
    int id = 0, id1 = 0, length = 0;
    FILE *p_file = NULL;
    printf("请输入一个id:");
    scanf("%d", &id);
    p_file = fopen("a.bin", "rb");
    if (p_file) {
        fseek(p_file, 0, SEEK_END);
        length = ftell(p_file);
        rewind(p_file);
        while(ftell(p_file) < length) {
            fread(&id1, sizeof(int), 1, p_file);
            if (id == id1) {
                printf("id已存在\n");
                break;
            }
            fseek(p_file, 24, SEEK_CUR);
        }
        if (ftell(p_file) >= length) {
            printf("id不存在\n");
        }
        fclose(p_file);
        p_file = NULL;
    }
    return 0;
}

 

<think>我们正在处理一个关于蓝牙错误的问题,用户遇到了两个错误信息: 1. Bluetooth: hci0: unexpected cc 0x0c12 length: 2 < 3 2. Bluetooth: hci0: Opcode 0x0c12 failed: -38 根据用户提供的引用问题描述,我们可以得知: - 用户是在安装或启动Ubuntu时遇到这个问题(引用[1][4])。 - 引用[1]提到使用蓝牙鼠标,并且蓝牙接口开启。 - 引用[2]解释了HCI(主机控制器接口)是访问蓝牙控制器的统一接口,并提到HCI数据包格式。 - 引用[3]提到当蓝牙USB适配器插入时,会调用hci_usb.c中的probe函数,并初始化接收任务。 - 引用[4]提到可能是软件驱动问题,并给出了进入命令行的方法。 错误分析: 错误信息中的“unexpected cc 0x0c12”表示收到了一个意外的命令完成事件(Command Complete event),操作码为0x0c12,并且数据长度比预期的短(实际长度2,期望至少3)。 第二个错误表示操作码0x0c12的命令执行失败,错误码-38(即ENOSYS,表示函数未实现)。 可能的原因: 1. 蓝牙固件或驱动问题:可能是蓝牙芯片的固件与当前驱动程序不兼容,或者驱动有问题。 2. 硬件问题:蓝牙适配器可能出现故障,或者USB连接问题。 3. 系统配置问题:蓝牙服务或相关模块加载不正确。 解决方案: 根据引用常见解决方法,我们可以尝试以下步骤: 步骤1:更新系统蓝牙相关软件 在终端中执行以下命令: ```bash sudo apt update sudo apt upgrade ``` 这可以确保系统是最新的,修复可能存在的软件缺陷。 步骤2:检查蓝牙硬件 使用以下命令检查蓝牙设备: ```bash hciconfig -a ``` 如果设备未显示,尝试重新插入蓝牙适配器(如果是USB的)。 步骤3:重置蓝牙 尝试重置蓝牙模块: ```bash sudo rmmod btusb # 卸载蓝牙模块 sudo modprobe btusb # 重新加载蓝牙模块 ``` 或者重启蓝牙服务: ```bash sudo systemctl restart bluetooth ``` 步骤4:检查内核模块参数(可选) 有时,添加内核模块参数可以解决问题。编辑文件`/etc/modprobe.d/btusb.conf`(如果不存在则创建): ```bash sudo nano /etc/modprobe.d/btusb.conf ``` 添加以下内容: ``` options btusb reset=1 ``` 保存并退出,然后重启系统或重新加载模块。 步骤5:禁用蓝牙电源管理 蓝牙电源管理有时会导致问题。我们可以尝试禁用它: 创建或编辑文件`/etc/modprobe.d/btusb_disable_pm.conf`: ```bash sudo nano /etc/modprobe.d/btusb_disable_pm.conf ``` 添加: ``` options btusb enable_autosuspend=0 ``` 然后重新加载模块或重启。 步骤6:更新或重新安装固件 查找蓝牙适配器的芯片型号(使用`lsusb`命令),然后去制造商的网站查找是否有更新的固件。或者,尝试重新安装固件包: ```bash sudo apt install --reinstall linux-firmware ``` 步骤7:检查内核日志 使用以下命令查看内核日志,以获取更多错误信息: ```bash dmesg | grep -i bluetooth ``` 这有助于进一步诊断问题。 步骤8:如果以上方法无效,尝试禁用蓝牙 如果暂时不需要蓝牙,可以在BIOS/UEFI中禁用蓝牙,或者通过内核参数禁用蓝牙模块。 编辑`/etc/modprobe.d/blacklist.conf`: ```bash sudo nano /etc/modprobe.d/blacklist.conf ``` 添加: ``` blacklist btusb ``` 然后重启。 注意:步骤8是最后的手段,将完全禁用蓝牙。 由于用户提到在安装Ubuntu时出现此问题,可能是在安装过程中蓝牙设备导致的。可以尝试在安装时拔掉蓝牙设备(如蓝牙鼠标),使用有线鼠标完成安装,安装后再尝试解决蓝牙问题。 另外,引用[4]中提到在启动界面报错无法进入系统,并提供了进入命令行的方法(Ctrl+Alt+F1~6)。如果错误导致系统无法启动,可以尝试在启动时进入恢复模式(Recovery Mode)或命令行,然后执行上述步骤(如更新、重置等)。 引用文献: [^1]:ubuntu安装失败Bluetooth hci0 unexpected cc 0x0c12 解决办法 [^2]:Bluetooth HCI [^3]:Bluetooth HCI Event的处理 [^4]:ubuntu启动界面报错,无法进入。报错Bluetooth 根据以上分析,我们给出详细的解决步骤。 如果问题仍未解决,建议提供更多日志信息(如完整的dmesg输出)或尝试更换蓝牙适配器。 相关问题: 1. 如何查看蓝牙适配器的芯片型号? 2. 如何从命令行启动蓝牙服务? 3. 如何查看蓝牙的详细日志? 4. 在Ubuntu中如何彻底卸载并重新安装蓝牙驱动? </think>### 解决蓝牙错误 `Bluetooth: hci0: unexpected cc 0x0c12 length: 2 < 3` `Bluetooth: hci0: Opcode 0x0c12 failed: -38` 的方法 根据引用内容分析,此错误通常由 **蓝牙固件/驱动不兼容** 或 **HCI(主机控制器接口)协议栈故障** 引起。以下是分步解决方案: --- ### 1. 更新蓝牙固件与驱动(关键步骤) ```bash # 更新系统与内核 sudo apt update && sudo apt upgrade -y sudo apt install --reinstall linux-firmware bluez # 重置蓝牙模块 sudo rmmod btusb sudo modprobe btusb sudo systemctl restart bluetooth ``` - **原理**:错误 `Opcode 0x0c12 failed: -38` 表示蓝牙芯片无法执行HCI指令(错误码 `-38 = ENOSYS`),通常因固件过旧导致[^2][^3]。 --- ### 2. 禁用蓝牙能模式 ```bash # 创建配置文件 echo "options btusb enable_autosuspend=0" | sudo tee /etc/modprobe.d/btusb_disable_pm.conf # 应用更改 sudo update-initramfs -u sudo reboot ``` - **原理**:能模式可能导致USB蓝牙适配器意外休眠,触发 `unexpected cc 0x0c12` 的HCI数据包异常[^2][^3]。 --- ### 3. 强制重置蓝牙硬件 ```terminal # 进入root模式 sudo -i # 重置HCI接口 echo 1 > /sys/kernel/debug/bluetooth/hci0/reset hciconfig hci0 reset ``` - **注意**:若系统卡在启动界面,按 `Ctrl+Alt+F2` 进入TTY命令行执行[^4]。 --- ### 4. 替换蓝牙协议栈(备用方案) 若使用第三方蓝牙设备(如USB适配器): ```bash # 卸载默认驱动 sudo apt remove bluez* sudo apt install blueman pulseaudio-module-bluetooth # 重新配对设备 bluetoothctl > power on > remove [设备MAC地址] > scan on > pair [新MAC地址] ``` - **适用场景**:品牌蓝牙外设(如Logitech)与Ubuntu默认协议栈冲突时[^1]。 --- ### 5. 终极方案:内核参数屏蔽错误 ```bash # 编辑GRUB配置 sudo nano /etc/default/grub # 在GRUB_CMDLINE_LINUX行末尾添加: btusb.reset_errors=1 ignore_loglevel # 更新并重启 sudo update-grub sudo reboot ``` - **效果**:忽略HCI层错误日志(可能影响定位新问题)[^3]。 --- ### 故障排查建议 1. **检查硬件连接**:拔插蓝牙适配器或更换USB端口 2. **查看完整日志**:`dmesg | grep -i bluetooth` 3. **尝试Live USB**:从Ubuntu安装介质启动,测试是否为硬件故障 4. **更换蓝牙设备**:部分Broadcom芯片兼容性较差 > **重要提示**:若错误出现在**安装过程中**(如引用[1]),建议先断开蓝牙外设完成安装,再按上述步骤修复[^1][^4]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值