You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言提取子字符串咨询:读取"c4 d5"格式字符串并拆分的两种实现方案

嘿,我来帮你搞定这个C语言字符串拆分的问题~你原来的代码出现异常,主要是两个关键问题在搞鬼:

  1. scanf("%s", action)只会读取空格前的内容,也就是说它只能拿到"c4",后面的"d5"根本没被读进action里;
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:42:56