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

如何修改C语言字符串分割代码以处理多组连续数据?

多组「姓名+父姓+母姓+专业+ID」字符串的C语言分割代码修改方案

问题背景

现有代码仅能正确分割单组格式为「姓名(首字母大写+后续小写)+父姓+母姓+专业+数字ID」的字符串,但无法处理多组该格式拼接的连续字符串(例如CristinaRodriguezRiveraComputacion210302414RamiroSilvaPerezIndustrial217890453...),需要对代码进行针对性修改。

核心修改点

  1. 让分割函数返回当前组的结束位置,支持循环处理下一组
  2. 修复ID字段的提取逻辑(原代码直接取到字符串末尾,多组场景下会包含下一组内容)
  3. 补充字符串终止符,避免内存溢出和乱码
  4. 添加循环逻辑,遍历处理所有分组

具体修改步骤

1. 修正complete_lowercase函数

原函数未给目标字符串添加终止符,且未处理边界越界问题,修改后:

int complete_lowercase(char dinamic[], int longdinamico, char destiny[], int ini, int max_dest_len) { 
    if (ini >= longdinamico || !isupper(dinamic[ini])) {
        destiny[0] = '\0';
        return ini;
    }
    int fin = ini + 1; 
    while (fin < longdinamico && islower(dinamic[fin])) { 
        ++fin; 
    }
    // 限制复制长度,避免目标数组溢出
    int copy_len = fin - ini;
    if (copy_len > max_dest_len - 1) {
        copy_len = max_dest_len - 1;
    }
    memcpy(destiny, &dinamic[ini], copy_len); 
    destiny[copy_len] = '\0'; // 添加字符串终止符
    return fin; 
}
  • 新增max_dest_len参数,限制复制长度防止溢出
  • 添加边界检查,避免越界访问
  • 给目标字符串添加'\0',确保是合法C字符串

2. 重写separate_data函数

将原无返回值的函数改为返回当前组处理后的结束索引,同时修正ID提取逻辑:

int separate_data(char dinamic[], int longdinamico, char name[], char father[], char mother[], char degree[], char id[], int max_field_len) { 
    int current_pos = complete_lowercase(dinamic, longdinamico, name, 0, max_field_len); 
    current_pos = complete_lowercase(dinamic, longdinamico, father, current_pos, max_field_len); 
    current_pos = complete_lowercase(dinamic, longdinamico, mother, current_pos, max_field_len); 
    current_pos = complete_lowercase(dinamic, longdinamico, degree, current_pos, max_field_len); 

    // 提取ID:从current_pos开始,直到非数字或字符串结束
    int id_start = current_pos;
    while (current_pos < longdinamico && isdigit(dinamic[current_pos])) {
        ++current_pos;
    }
    int id_len = current_pos - id_start;
    if (id_len > max_field_len - 1) {
        id_len = max_field_len - 1;
    }
    memcpy(id, &dinamic[id_start], id_len);
    id[id_len] = '\0';

    return current_pos; // 返回当前组的结束位置,作为下一组的起始
}
  • 改为返回int类型,返回当前组处理完后的索引
  • 单独处理ID字段:仅提取连续数字部分,避免包含下一组的内容
  • 统一使用max_field_len限制字段长度,防止溢出

3. 修改main函数,添加循环处理逻辑

原函数仅处理一次分组,修改后循环处理所有分组:

int main(){ 
    FILE* ent = fopen("DatosEntrada.txt","r"); 
    FILE* sal = fopen("SalidaBytes.txt","a"); 
    const int MAX_FIELD_LEN = 15; // 统一字段最大长度

    if(ent != NULL){ 
        char name[MAX_FIELD_LEN]; 
        char father[MAX_FIELD_LEN]; 
        char mother[MAX_FIELD_LEN]; 
        char degree[MAX_FIELD_LEN]; 
        char id[MAX_FIELD_LEN]; 

        // 获取文件长度并读取全部内容
        fseek(ent, 0, SEEK_END); 
        int longarch = ftell(ent); 
        rewind(ent); 

        char dinamic[longarch+1]; 
        fscanf(ent,"%s", dinamic); // 注意:&dinamic改为dinamic,数组名本身是指针
        dinamic[longarch] = '\0'; // 确保字符串终止

        int current_pos = 0;
        // 循环处理每一组数据,直到处理完整个字符串
        while (current_pos < longarch) {
            // 重置字段为空格
            memset(name, ' ', MAX_FIELD_LEN); 
            memset(father, ' ', MAX_FIELD_LEN); 
            memset(mother, ' ', MAX_FIELD_LEN); 
            memset(degree, ' ', MAX_FIELD_LEN); 
            memset(id, ' ', MAX_FIELD_LEN); 

            // 处理当前组,更新current_pos到下一组起始
            current_pos = separate_data(dinamic, longarch, name, father, mother, degree, id, MAX_FIELD_LEN); 

            // 写入文件(注意:这里会保留字段的空格填充,和原逻辑一致)
            fwrite(name, sizeof(char), MAX_FIELD_LEN, sal); 
            fwrite(father, sizeof(char), MAX_FIELD_LEN, sal); 
            fwrite(mother, sizeof(char), MAX_FIELD_LEN, sal); 
            fwrite(degree, sizeof(char), MAX_FIELD_LEN, sal); 
            fwrite(id, sizeof(char), MAX_FIELD_LEN, sal); 
        }

        printf("\n所有分组处理完成,已写入文件\n"); 
        fclose(ent); 
        fclose(sal); 

    }else{ 
       fprintf(stdout, "ERROR: %s", strerror(errno)); 
    } 
    return 0;
}
  • 添加current_pos变量跟踪当前处理位置,循环处理所有分组
  • 修正fscanf的参数错误(原代码&dinamic是错误的,数组名直接作为指针即可)
  • 统一用MAX_FIELD_LEN管理字段长度,提高可维护性
  • 每次处理前重置字段为空格,保持原代码的输出格式

修改后的完整代码

#include <stdio.h> 
#include <errno.h> 
#include <ctype.h> 
#include <string.h> 

int complete_lowercase(char dinamic[], int longdinamico, char destiny[], int ini, int max_dest_len) { 
    if (ini >= longdinamico || !isupper(dinamic[ini])) {
        destiny[0] = '\0';
        return ini;
    }
    int fin = ini + 1; 
    while (fin < longdinamico && islower(dinamic[fin])) { 
        ++fin; 
    }
    int copy_len = fin - ini;
    if (copy_len > max_dest_len - 1) {
        copy_len = max_dest_len - 1;
    }
    memcpy(destiny, &dinamic[ini], copy_len); 
    destiny[copy_len] = '\0';
    return fin; 
} 

int separate_data(char dinamic[], int longdinamico, char name[], char father[], char mother[], char degree[], char id[], int max_field_len) { 
    int current_pos = complete_lowercase(dinamic, longdinamico, name, 0, max_field_len); 
    current_pos = complete_lowercase(dinamic, longdinamico, father, current_pos, max_field_len); 
    current_pos = complete_lowercase(dinamic, longdinamico, mother, current_pos, max_field_len); 
    current_pos = complete_lowercase(dinamic, longdinamico, degree, current_pos, max_field_len); 

    int id_start = current_pos;
    while (current_pos < longdinamico && isdigit(dinamic[current_pos])) {
        ++current_pos;
    }
    int id_len = current_pos - id_start;
    if (id_len > max_field_len - 1) {
        id_len = max_field_len - 1;
    }
    memcpy(id, &dinamic[id_start], id_len);
    id[id_len] = '\0';

    return current_pos;
} 

int main(){ 
    FILE* ent = fopen("DatosEntrada.txt","r"); 
    FILE* sal = fopen("SalidaBytes.txt","a"); 
    const int MAX_FIELD_LEN = 15;

    if(ent != NULL){ 
        char name[MAX_FIELD_LEN]; 
        char father[MAX_FIELD_LEN]; 
        char mother[MAX_FIELD_LEN]; 
        char degree[MAX_FIELD_LEN]; 
        char id[MAX_FIELD_LEN]; 

        fseek(ent, 0, SEEK_END); 
        int longarch = ftell(ent); 
        rewind(ent); 

        char dinamic[longarch+1]; 
        fscanf(ent,"%s", dinamic);
        dinamic[longarch] = '\0';

        int current_pos = 0;
        while (current_pos < longarch) {
            memset(name, ' ', MAX_FIELD_LEN); 
            memset(father, ' ', MAX_FIELD_LEN); 
            memset(mother, ' ', MAX_FIELD_LEN); 
            memset(degree, ' ', MAX_FIELD_LEN); 
            memset(id, ' ', MAX_FIELD_LEN); 

            current_pos = separate_data(dinamic, longarch, name, father, mother, degree, id, MAX_FIELD_LEN); 

            fwrite(name, sizeof(char), MAX_FIELD_LEN, sal); 
            fwrite(father, sizeof(char), MAX_FIELD_LEN, sal); 
            fwrite(mother, sizeof(char), MAX_FIELD_LEN, sal); 
            fwrite(degree, sizeof(char), MAX_FIELD_LEN, sal); 
            fwrite(id, sizeof(char), MAX_FIELD_LEN, sal); 
        }

        printf("\n所有分组处理完成,已写入文件\n"); 
        fclose(ent); 
        fclose(sal); 

    }else{ 
       fprintf(stdout, "ERROR: %s", strerror(errno)); 
    } 
    return 0;
}

内容的提问来源于stack exchange,提问作者SwagKiller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 05:18:25