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

在C语言token循环中调用函数触发段错误,求排查方案

问题分析与修复方案

你的段错误核心原因是直接修改strtok返回的原缓冲区指针指向的内容,导致缓冲区溢出,进而破坏内存结构(包括strtok的内部状态)。

具体问题点

  1. strtok返回的token指针指向sentence_copy数组内部的内存区域,该区域的空间仅为原单词长度+1。但转换后的猪拉丁语单词更长(比如cat→atcay,长度从3变为5),直接在原位置执行strcpy和strcat会溢出,覆盖数组其他数据甚至越界访问内存。
  2. 代码未处理全辅音单词(比如myth)的情况,此时first_vowel保持-1,直接执行strcat(input, end)依然可能触发缓冲区溢出。

修复后的代码

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

// 转换单个单词为猪拉丁语,结果存入提前分配好的output缓冲区
void pigLatinConsonant(const char input[], char output[]) {
    const char end[] = "ay";
    int length = strlen(input);
    int first_vowel = -1;
   
    // 查找第一个元音(支持大小写)
    for (int i = 0; i < length; i++) {
        char c = tolower(input[i]);
        if (strchr("aeiou", c)) {
            first_vowel = i;
            break;
        }
    }

    if (first_vowel != -1) {
        // 先拷贝元音起始的部分
        strcpy(output, input + first_vowel);
        // 拼接开头的辅音簇
        strncat(output, input, first_vowel);
    } else {
        // 全辅音单词直接拷贝原内容
        strcpy(output, input);
    }
    // 拼接后缀"ay"
    strcat(output, end);
}

int main() {
    char sentence[100];
    printf("Enter a sentence: ");

    fgets(sentence, sizeof(sentence), stdin);
    // 移除fgets读取的换行符
    sentence[strcspn(sentence, "\n")] = '\0';

    char sentence_copy[sizeof(sentence)];
    strcpy(sentence_copy, sentence);

    char *token = strtok(sentence_copy, " ");
    // 为转换后的单词分配足够空间(原单词长度+3,满足最长扩展需求)
    char translated_word[100];

    while (token != NULL) {
        pigLatinConsonant(token, translated_word);
        printf("Translated word: %s\n", translated_word);
        token = strtok(NULL, " ");
    }

    return 0;
}

关键修改说明

  • 重构pigLatinConsonant函数,新增独立的输出缓冲区,不再直接修改原输入字符串,彻底避免缓冲区溢出。
  • 补充全辅音单词的处理逻辑,保证所有场景下的内存安全。
  • 移除fgets带入的换行符,避免最后一个单词的转换被干扰。
  • 新增大小写元音兼容处理,提升代码通用性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:05:00