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

C 语言第 10 天学习笔记:字符串基础操作与相关函数

C语言学习笔记:数组与字符串及综合案例

内容提要

  • 数组
    • 字符串基础操作
    • 字符串相关函数
  • 综合案例:学生成绩管理系统v1.0

数组与字符串基础操作

在用格式化说明符%s进行输入输出时,其输入输出项均为数组名。输入时,相邻字符串需用空格分隔,系统会自动在字符串后加\0;输出时,遇到\0则结束输出。字符串操作需使用系统提供的API函数。

字符串输入

scanf

  • 语法scanf("%s", 数组名);
  • 说明:数组需为char类型,输入后默认追加\0
  • 注意:输入字符串不能包含空格,否则遇空格结束。
  • 案例
#include <stdio.h>int main(int argc, char *argv[]) {char name[20]; // 存储姓名的字符数组printf("请输入您的名字:\n");scanf("%s", name); // 接收输入的字符串printf("您的姓名是%s\n", name);return 0;
}

fgets

  • 语法fgets(数组名, 数组容量, stdin);
  • 功能:从键盘录入字符串到字符数组,返回数组首地址(12位16进制数)。
  • 说明:可接收含空格或换行的字符串,需手动处理可能包含的\n
  • 案例
#include <stdio.h>int main(int argc, char *argv[]) {char name[20]; // 需指定容量int len = sizeof(name) / sizeof(name[0]); // 计算数组容量printf("请输入您的姓名:\n");fgets(name, len, stdin); printf("您的姓名是%s\n", name);return 0;
}
  • 注意
    • 无空格/换行的字符串可使用scanffgets
    • 含空格/换行的字符串只能用fgets

gets(危险,C11移出)

  • 语法gets(数组名);
  • 功能:从键盘录入字符串到字符数组,返回数组首地址。
  • 说明:可接收含空格/换行的字符串,但存在缓冲区溢出风险,已被C11标准移除。

字符串输出

printf

  • 语法printf("%s", 数组名);
  • 说明%s支持字符串常量、字符数组,均以字符串形式输出,遇\0结束。
  • 案例:同fgets案例中的输出部分。

fputs

  • 语法fputs(数组名, stdout);
  • 功能:输出字符串,支持包含转义字符(以\开头)。
  • 案例
#include <stdio.h>int main(int argc, char *argv[]) {char arr[] = "hi yifanjiao\neat!\n";// 两种输出方式printf("%s", arr);fputs(arr, stdout);return 0;
}

puts(危险,C11移出)

  • 语法puts(数组名称);
  • 功能:输出字符串,支持转义字符,但存在安全风险,已被C11移除。

字符串相关函数

需引入头文件#include <string.h>

字符串拼接(strcat)

  • 语法strcat(字符数组, 需要拼接的字符串/字符数组/字符指针);
  • 说明
    • 参数1必须是字符数组,且剩余空间需足够容纳参数2;
    • 拼接时会删除除最后一个\0以外的所有\0
  • 案例
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[]) {char name[20];printf("请输入您的名字:\n");fgets(name, sizeof(name)/sizeof(name[0]), stdin);fputs(strcat(name, "你好!"), stdout); // 拼接并输出printf("\n");return 0;
}

字符串拷贝(strcpy)

  • 语法strcpy(数组名, 字符串);
  • 功能:类似将字符串赋值给字符数组(数组不可直接赋值,需用此函数)。
  • 区别strcat是追加(如"a"+“b"→"ab”),strcpy是覆盖(如"a"+“b"→"b”)。
  • 案例
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[]) {char name[50] = "hello";printf("初始化后: %s\n", name);strcpy(name, "my"); // 覆盖原有内容printf("赋值后: %s\n", name);return 0;
}

字符串比较(strcmp)

  • 语法strcmp(字符串1, 字符串2);
  • 返回值
    • 相等返回0;
    • 字符串1>字符串2返回正数;
    • 字符串1<字符串2返回负数。
  • 说明:逐字符比较ASCII值,不可用==直接比较字符串。
  • 案例
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[]) {char username[20], password[8];printf("---------用户登录--------\n");printf("请输入用户名:\n");scanf("%s", username);printf("请输入密码:\n");scanf("%s", password);// 校验用户名和密码if (!strcmp(username, "admin") && !strcmp(password, "123456")) {printf("登录成功!\n");} else {printf("用户名或密码错误!\n");}return 0;
}

字符串长度(strlen)

  • 语法strlen(字符串);
  • 功能:返回字符串实际字符数(遇\0结束,不含\0;无\0则返回数组长度)。
  • 案例
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[]) {char s4[] = "hello";printf("数组长度: %lu\n字符串长度: %lu\n", sizeof(s4)/sizeof(s4[0]), strlen(s4)); // 数组长度6,字符串长度5return 0;
}

综合案例:学生成绩管理系统v1.0

需求

  1. 存储最多50名学生信息(无结构体);
  2. 每个学生包含:学号(字符数组)、姓名(字符数组)、3门课程成绩(一维数组);
  3. 功能:添加学生信息、显示所有信息、计算平均分、查找最高分科目、退出系统。

代码实现

#include <stdio.h>
#include <string.h>/* 系统常量定义 */
#define MAX_STU 50        // 最大学生数量
#define NAME_LEN 20       // 姓名最大长度(含\0)
#define ID_LEN 8          // 学号最大长度(含\0)
#define COURSE_NUM 3      // 课程数量/* 全局数据存储数组 */
char stu_id[MAX_STU][ID_LEN];          // 学号数组
char stu_name[MAX_STU][NAME_LEN];      // 姓名数组
int scores[MAX_STU][COURSE_NUM];       // 成绩数组
int stu_count = 0;                     // 实际学生数量/* 课程名称 */
char COURSE_NAMES[COURSE_NUM][NAME_LEN] = {"语文", "数学", "英语"};/*** 查找最高分科目及对应学生*/
void find_max() {if (stu_count == 0) {printf("系统提示:当前没有学生信息!\n");return;}int max_score = -1;int max_stu_idx = -1, max_course_idx = -1;// 遍历所有学生和科目for (int i = 0; i < stu_count; i++) {for (int j = 0; j < COURSE_NUM; j++) {if (scores[i][j] > max_score) {max_score = scores[i][j];max_stu_idx = i;max_course_idx = j;}}}// 输出结果printf("系统最高分:\n");printf("学生:%s\n", stu_name[max_stu_idx]);printf("学号:%s\n", stu_id[max_stu_idx]);printf("科目:%s\n", COURSE_NAMES[max_course_idx]);printf("分数:%d\n\n", max_score);
}/*** 计算指定学生平均分*/
void calc_avg() {if (stu_count == 0) {printf("系统提示:当前没有学生信息!\n");return;}char target_id[ID_LEN];printf("请输入要查询的学生学号:");scanf("%7s", target_id);while (getchar() != '\n'); // 清空缓冲区// 查找学生for (int i = 0; i < stu_count; i++) {if (strcmp(stu_id[i], target_id) == 0) {float sum = 0;for (int j = 0; j < COURSE_NUM; j++) sum += scores[i][j];printf("学生 %s(学号:%s)的平均分:%.2f\n\n", stu_name[i], stu_id[i], sum / COURSE_NUM);return;}}printf("系统提示:未找到学号为 %s 的学生!\n\n", target_id);
}/*** 显示所有学生信息*/
void show_all() {if (stu_count == 0) {printf("系统提示:当前没有学生信息!\n");return;}printf("\n=== 当前所有学生信息 ===\n");// 表头printf("%-10s%-20s", "学号", "姓名");for (int i = 0; i < COURSE_NUM; i++) printf("%-10s", COURSE_NAMES[i]);printf("\n");// 内容for (int i = 0; i < stu_count; i++) {printf("%-10s%-20s", stu_id[i], stu_name[i]);for (int j = 0; j < COURSE_NUM; j++) printf("%-10d", scores[i][j]);printf("\n");}printf("\n系统统计:共%d名学生\n\n", stu_count);
}/*** 获取有效成绩(0~100)*/
int get_valid_score(const char* course) {int score;do {printf("请输入%s成绩(0~100):", course);scanf("%d", &score);while (getchar() != '\n'); // 清理缓存if (score < 0 || score > 100) {printf("输入错误:成绩必须在0~100之间!\n");}} while (score < 0 || score > 100);return score;
}/*** 添加学生信息*/
void add_student() {if (stu_count >= MAX_STU) {printf("系统提示:学生数量已达上限%d人!\n", MAX_STU);return;}printf("\n=== 正在添加第%d个学生 ===\n", stu_count + 1);// 输入学号printf("请输入学号(最多%d位数字):", ID_LEN - 1);scanf("%7s", stu_id[stu_count]);while (getchar() != '\n'); // 清理缓冲区// 输入姓名printf("请输入姓名(最多%d位字符):", NAME_LEN - 1);fgets(stu_name[stu_count], NAME_LEN, stdin);// 去除换行符stu_name[stu_count][strcspn(stu_name[stu_count], "\n")] = '\0';// 输入成绩printf("请依次输入各科成绩:\n");for (int i = 0; i < COURSE_NUM; i++) {scores[stu_count][i] = get_valid_score(COURSE_NAMES[i]);}stu_count++;printf("成功添加学生:%s(学号:%s)\n", stu_name[stu_count - 1], stu_id[stu_count - 1]);
}/*** 显示主菜单*/
void show_menu() {printf("\n======== 主菜单 ========\n");printf("1. 添加学生信息\n");printf("2. 显示所有学生信息\n");printf("3. 查询学生平均分\n");printf("4. 查询最高分科目\n");printf("5. 退出系统\n");
}/*** 入口函数*/
int main(int argc, char *argv[]) {int choice;printf("= 学生成绩管理系统 V1.0 =\n");// 主循环while (1) {show_menu();// 获取用户选择if (scanf("%d", &choice) != 1) {while (getchar() != '\n'); // 清空无效输入printf("输入错误:请输入1~5的数字!\n");continue;}// 执行对应功能switch (choice) {case 1:add_student();break;case 2:show_all();break;case 3:calc_avg();break;case 4:find_max();break;case 5:printf("感谢使用学生成绩管理系统,再见!\n");return 0;default:printf("输入错误:请输入1~5的有效选项!\n");}}return 0;
}

章节作业

一维数组练习题

  1. 键盘录入数列,用冒泡排序从大到小排序;
  2. 输入年、月、日,计算该日是当年第几天;
  3. 录入数列,求最大数、最小数、均值;
  4. 判断数列是否为回文(如12321、abba);
  5. 存储10个整数,输入一个数,找出其下标;
  6. 录入10个学员成绩:
    • 输出不及格成绩及下标;
    • 求最高分、最低分的下标;
    • 求总成绩及平均分。

二维数组练习题

  1. 二维数组中查找用户输入的数,返回行列位置;
  2. 求二维整型数组所有元素平均值、每行最大值、每列最小值;
  3. 计算行列相等数组的主对角线元素和;
  4. 计算矩阵下三角元素的和;
  5. 电影院某排某列有礼包(行和列的平方和为512),找出位置(20排,每排25座)。

字符数组练习题

  1. 读取字符串并反转输出;
  2. 判断字符串是否为回文。

思考题(选做)

  1. 求出矩阵的鞍点(行上最大且列上最大的元素)。
http://www.xdnf.cn/news/1196569.html

相关文章:

  • 机器学习特征选择 explanation and illustration of ANOVA
  • java开闭原则 open-closed principle
  • 影刀RPA_初级课程_玩转影刀自动化_网页操作自动化
  • 【机器学习深度学习】NLP评价指标 BLEU 和 ROUGE
  • python优秀案例:基于python flask实现的小说文本数据分析与挖掘系统,包括K-means聚类算法和LDA主题分析
  • 用KNN实现手写数字识别:基于 OpenCV 和 scikit-learn 的实战教学 (超级超级超级简单)
  • Kafka——消费者组消费进度监控都怎么实现?
  • 牛客周赛101 D题 题解
  • 五、搭建springCloudAlibaba2021.1版本分布式微服务-gateway网关
  • 力扣热题100----------53最大子数组和
  • 零基础学习性能测试第五章:Tomcat的性能分析与调优-Tomcat原理,核心配置项,性能瓶颈分析,调优
  • RAG(检索增强生成)
  • 探秘CommonJS:Node.js模块化核心解析
  • redis主从复制、哨兵机制底层原理
  • XML Schema 指示器:全面解析与深度应用
  • 齐护Ebook科技与艺术Steam教育套件 可图形化micropython Arduino编程ESP32纸电路手工
  • xgboost 机器学习在生物信息学中的应用
  • 【橘子分布式】gRPC(番外篇-客户端重试机制)
  • PostGIS面试题及详细答案120道之 (021-030 )
  • Java面试精进:测试、监控与序列化技术全解析
  • Netty中 ? extends Future<? super V>这种的写法的理解
  • 51c自动驾驶~合集9
  • Java面试宝典:MySQL执行原理二
  • Spring AI 项目实战(二十一):Spring Boot + AI +DeepSeek驱动的智能题库系统(附完整源码)
  • bash的特性-常用的通配符
  • AWS免费套餐全面升级:企业降本增效与技术创新解决方案
  • HCIP---MGRE实验
  • 电子电气架构 --- 软件bug的管理模式
  • logstash采集springboot微服务日志
  • 【奔跑吧!Linux 内核(第二版)】第4章:内核编译和调试