C语言提取子字符串咨询:读取"c4 d5"格式字符串并拆分的两种实现方案
嘿,我来帮你搞定这个C语言字符串拆分的问题~你原来的代码出现异常,主要是两个关键问题在搞鬼:
scanf("%s", action)只会读取空格前的内容,也就是说它只能拿到"c4",后面的"d5"根本没被读进action里;str1和str2定义成char[2],用strncpy复制2个字符后,没有手动添加字符串终止符'\0',C语言里字符串必须靠这个终止符标识结束,少了它后续操作(比如打印)就会出现乱码或者其他未定义行为。
下面分别给你基于char[]和char*的可行解决方案,都是适合新手理解的写法:
一、使用char[]的解决方案
这种方式用数组存储数据,逻辑直观,适合刚学C的朋友:
最简单的写法:直接读取两个部分
既然输入是"c4 d5"这种空格分隔的格式,完全可以让scanf直接帮你拆分,不用先读整个字符串再手动处理:
#include <stdio.h> int main() { // 定义数组时留足空间:2个字符+1个终止符,所以用char[3] char str1[3], str2[3]; // %s %s 会自动跳过空格,分别读取两个部分 scanf("%s %s", str1, str2); printf("str1: %s\nstr2: %s\n", str1, str2); return 0; }
按你原思路:先读整行再拆分
如果你一定要先把整个输入读到一个数组里再拆分,那要注意数组大小和终止符的问题:
#include <stdio.h> #include <string.h> int main() { // "c4 d5"一共5个字符,加终止符需要6个位置,所以定义char[6] char action[6]; char str1[3], str2[3]; // %[^\n] 表示读取直到换行符的所有字符(包括空格) scanf("%[^\n]", action); // 复制前2个字符到str1,手动加终止符 strncpy(str1, action, 2); str1[2] = '\0'; // 从索引3的位置开始复制2个字符到str2(索引2是空格),同样加终止符 strncpy(str2, &action[3], 2); str2[2] = '\0'; printf("str1: %s\nstr2: %s\n", str1, str2); return 0; }
二、使用char*的解决方案
指针操作是C语言的核心,这里给两种常见的写法:
方式1:指针指向栈上的数组(新手友好)
本质还是用数组,但用指针来定位和操作内存:
#include <stdio.h> #include <string.h> int main() { char action[6]; char *ptr1, *ptr2; char str1[3], str2[3]; scanf("%[^\n]", action); ptr1 = action; // 指针指向action的起始位置 strncpy(str1, ptr1, 2); str1[2] = '\0'; ptr2 = action + 3; // 跳过前3个字符(c、4、空格),指向d5的起始位置 strncpy(str2, ptr2, 2); str2[2] = '\0'; printf("str1: %s\nstr2: %s\n", str1, str2); return 0; }
方式2:动态分配堆内存(进阶写法)
如果需要在堆上存储数据(比如数据需要在函数间传递),可以用malloc分配内存,记得用完要释放:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { // 动态分配内存,要计算好所需大小 char *action = (char*)malloc(6 * sizeof(char)); char *str1 = (char*)malloc(3 * sizeof(char)); char *str2 = (char*)malloc(3 * sizeof(char)); // 检查内存是否分配成功 if (!action || !str1 || !str2) { printf("内存分配失败!\n"); return 1; } scanf("%[^\n]", action); strncpy(str1, action, 2); str1[2] = '\0'; strncpy(str2, action + 3, 2); str2[2] = '\0'; printf("str1: %s\nstr2: %s\n", str1, str2); // 释放堆内存,避免内存泄漏 free(action); free(str1); free(str2); return 0; }
最后再划几个重点
- 永远记住:C语言的字符串必须以
'\0'结尾,定义字符数组时一定要留够位置放这个终止符; scanf("%s")会自动跳过前导空白,读取到下一个空白为止,所以对于空格分隔的输入,直接用scanf("%s %s", ...)是最省心的;- 用指针时,一定要确保指针指向的内存是合法可访问的,别瞎指哦~
内容的提问来源于stack exchange,提问作者user5398179
相关产品推荐
相关产品推荐

