一、常用库函数
1. sprintf函数
- 功能:将格式化字符串内容放入指定地址空间
- 用途:
- 常用于程序中获得printf打印的内容
- 可以用于字符串拼接
2. sscanf函数
- 功能:从指定空间中接收格式化字符串
- 特点:字符串格式非常固定,符合scanf常用的格式
3. strtok函数
- 功能:字符串分割函数,能够根据指定的字符集对字符串进行分割
- 使用示例:
strtok(pstr, " "); // 将pstr指向的字符串遇到' '分割
strtok(NULL, " "); // 将上次分割剩余的内容再按照' '分割
strtok(NULL, ",?:"); // 将上次分割剩余的内容遇到',','?'分割
4. strstr函数
- 功能:在字符串中查找子串出现的位置
- 返回值:如果没有找到返回NULL
二、C语言内存常见问题调试方法
1. 程序错误分类
语法错误
- 错误(error):语法错误,无法生成对应的二进制文件
- 告警(Warning):语法警告,语法有可能会出现问题,不影响二进制文件的生成,程序运行可能会出错
逻辑错误
- 现象:程序运行结果和预期不符
2. 调试方法
打印法
在可能出错的位置加入打印,查看对应的结果是否与预期一致,如果一致在后续的代码中继续加入打印,直到不满足预期为止,则完成对错误的定位
gdb调试
根据问题单步调试,直到找到错误为止:
- n:分步执行
- c:执行到下一处断点为止
- s:进入函数内调试
- p:打印变量
三、内存问题调查
1. 内存越界(内存溢出)
- 现象:代码会出现偶现性、必现性的BUG,程序代码不稳定,数据被莫名其妙的修改
- 问题原因:指针的越界访问,特别是字符串越界访问
- 有越界风险的函数:strcpy、strcat、strcmp、sprintf
- 推荐的安全函数:strncpy、strncat、strncmp、snprintf
- 替换示例:
strncpy(dst, src, sizeof(dst)-1); // 替换 strcpy(dst, src);
2. 段错误调试
- 现象:程序运行后报错 Segmentation fault (core dumped)
- 问题原因:错误使用指针,访问非法空间
- 解决方法:
- 打印法:加入打印,前一句能打印,后一句无法打印,证明中间代码出现问题
- gdb调试段错误:
- 编译时代码加入-g选项
- 程序代码段错误时会产生core文件
- 修改core配置文件并允许生成core文件:ulimit -c unlimited
- 使用gdb调试段错误:gdb a.out core
3. 内存泄露
- 现象:长时间运行代码,剩余内存空间越来越少
- 问题原因:内存泄露,申请的空间没有被释放,所以不断有空间被申请,造成可用空间越来越小
- 解决方法:使用valgrind工具
valgrind –tool=memcheck –check-leak=full ./a.out
4. 安装valgrind工具
让虚拟机能够上网:
- 打开"虚拟机" → “设置” → “网络适配器” → 选择"NAT模式" → 点击"确定"
- 设置Ubuntu的IP地址为自动获取IP地址
- 修改网卡配置文件:sudo vim /etc/network/interfaces
- 重启虚拟机:sudo shutdown -r now
- 测试网络:ping 8.8.8.8
配置apt-get工具集:
- 打开"Ubuntu Software Center"
- 右键图标选择"Software & Updates"
- 源选择aliyun
- 清除旧源:sudo apt-get autoclean
- 更新新源:sudo apt-get update
- 重建软件源依赖关系:sudo apt-get install -f
安装valgrind:
sudo apt-get install valgrind
每日练习
从终端接收一个字符串,统计字符中另一个子串出现的次数。
#include <stdio.h>
int Mystrcnt(char *pstr,char *pstr2)
{
int len2 = 0;
int i = 0;
int j = 0;
int cnt1 = 0;
while(pstr2[i] != 0)
{
i++;
}
len2 = i;
i = 0;
while(pstr[i] != 0)
{
if(pstr[i] == pstr2[j])
{
if(j == len2 – 1)
{
cnt1++;
}
j++;
i++;
}
else
{
j = 0;
i++;
}
}
return cnt1;
}
int main(void)
{
char str2[32] = {0};
char str[32] = {0};
int con = 0;
gets(str);
gets(str2);
con = Mystrcnt(str,str2);
printf("字符串里面%s的个数是%d\\n",str2,con);
return 0;
}
网硕互联帮助中心






评论前必须登录!
注册