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

如何移除字符串单数字长除法输出末尾的随机Unicode符号?

字符串大数除以单数字输出乱码问题解决

需求:实现函数接收字符串形式的大数和单个数字,执行长除法,返回「商R余数」格式的字符串。

原代码

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

char* str_div_by_digit(const char* num,int digit)
{
    char *ans=malloc(sizeof(char)*100);

    int index = 0;
    int n = strlen(num);
    int dividend = num[index] - 48;

    while(dividend < digit && index+1 < n)
    {
        dividend = dividend * 10 + (num[++index] - 48);
    }
    int i = 0;
    while(n > index)
    {
        char ans1 = 48 + (dividend / digit);
        ans[i++] = ans1;
        if(index == n-1)
        {
        dividend = dividend % digit;
        index++;
        }
        else
        {
        dividend = (dividend % digit) * 10 + (num[++index] - 48);
        }
    }
    int x = strlen(ans)-1;
    if(x==0)
    {
        ans[i++] = 48;
        dividend = dividend % digit;
    }

    ans[i++] = 'R';
    ans[i] = 48 + dividend;
    
  //void free(void *num);

    void free(void *ans); // Thanks @WhozCraig for pointing this out.

    return ans;
}

int main() 
{    
    printf("%s\n",str_div_by_digit("15",6));
    printf("%s",str_div_by_digit("15002",5));
    printf("%s\n",str_div_by_digit("10000000000000000000000000000003",5));
    printf("%s",str_div_by_digit("1237657129312587312493712539",7));
}

输出异常

C:\Users\MyName\Desktop\Whatever> program.exe
2R3 // Correct
3000R2╬ // Correct except for last character.
2000000000000000000000000000000R3 // Correct
176808161330369616070530362R5☻►☻ // Correct except for last character(s?).

问题分析与修复

出现乱码的核心原因是C语言字符串必须以'\0'(空字符)结尾,原代码中给ans赋值完余数后没有添加终止符,printf会持续读取内存直到遇到'\0',导致末尾出现随机乱码。此外还有几个潜在问题需要修复:

  1. 添加字符串终止符:在赋值完余数后,必须添加'\0'标记字符串结束:

    ans[i++] = 'R';
    ans[i++] = 48 + dividend;
    ans[i] = '\0'; // 新增终止符
    
  2. 修复内存分配大小:原代码固定分配100字节,对于超长输入(比如第三个测试用例的31位数字)会导致内存不足,应该根据输入字符串长度动态分配:

    // 商最多和原数字长度相同,加上R、余数和终止符,分配strlen(num)+3足够
    char *ans = malloc(sizeof(char) * (strlen(num) + 3));
    if (ans == NULL) { // 增加内存分配失败判断
        return NULL;
    }
    
  3. 移除错误的free声明:原代码中void free(void *ans);是错误的重复声明,直接删除即可。同时main函数中要记得释放返回的内存,避免内存泄漏:

    int main() 
    {    
        char *res1 = str_div_by_digit("15",6);
        printf("%s\n", res1);
        free(res1);
        
        char *res2 = str_div_by_digit("15002",5);
        printf("%s\n", res2);
        free(res2);
        
        char *res3 = str_div_by_digit("10000000000000000000000000000003",5);
        printf("%s\n", res3);
        free(res3);
        
        char *res4 = str_div_by_digit("1237657129312587312493712539",7);
        printf("%s\n", res4);
        free(res4);
    }
    
  4. 修复商为0的处理逻辑:原代码中strlen(ans)-1的计算是错误的(此时ans还没有终止符,strlen结果不确定),应该直接判断是否没有写入任何商字符:

    // 替换原有的x相关逻辑
    if (i == 0) { // 如果没有写入任何商数字,说明商是0
        ans[i++] = '0';
    }
    

修复后的完整代码

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

char* str_div_by_digit(const char* num,int digit)
{
    if (digit == 0) { // 避免除以0
        return NULL;
    }
    // 动态分配足够内存
    size_t num_len = strlen(num);
    char *ans = malloc(sizeof(char) * (num_len + 3));
    if (ans == NULL) {
        return NULL;
    }

    int index = 0;
    int n = num_len;
    int dividend = num[index] - '0'; // 用'0'代替48更直观

    // 凑够大于等于digit的被除数
    while(dividend < digit && index + 1 < n)
    {
        dividend = dividend * 10 + (num[++index] - '0');
    }

    int i = 0;
    while(n > index)
    {
        ans[i++] = '0' + (dividend / digit);
        if(index == n - 1)
        {
            dividend = dividend % digit;
            index++;
        }
        else
        {
            dividend = (dividend % digit) * 10 + (num[++index] - '0');
        }
    }

    // 处理商为0的情况
    if (i == 0) {
        ans[i++] = '0';
    }

    // 添加R和余数,加上终止符
    ans[i++] = 'R';
    ans[i++] = '0' + dividend;
    ans[i] = '\0';

    return ans;
}

int main() 
{    
    char *res1 = str_div_by_digit("15",6);
    printf("%s\n", res1);
    free(res1);
    
    char *res2 = str_div_by_digit("15002",5);
    printf("%s\n", res2);
    free(res2);
    
    char *res3 = str_div_by_digit("10000000000000000000000000000003",5);
    printf("%s\n", res3);
    free(res3);
    
    char *res4 = str_div_by_digit("1237657129312587312493712539",7);
    printf("%s\n", res4);
    free(res4);
    
    // 测试商为0的情况
    char *res5 = str_div_by_digit("5",10);
    printf("%s\n", res5);
    free(res5);
    
    return 0;
}

修复后输出

2R3
3000R2
2000000000000000000000000000000R3
176808161330369616070530362R5
0R5

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:30:53