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

在C语言中如何将字符串转为长整型且保留前导零?

问题本质:整型不存储前导零

long/long long等数值类型仅存储数值本身,前导零属于字符串的格式信息,并非数值的一部分。因此无论用strtol还是sscanf,转换为整型后前导零必然丢失——这是数值类型的特性,无法通过转换函数解决。

你的实际需求是处理链表中的超长数字求和,当前代码还存在两个致命问题:

  1. 链表拼接的字符串可能长达500位,远超long long的存储范围(最多19位),会直接导致数值溢出、计算错误;
  2. 依赖整型反转的逻辑在溢出后完全失效。

正确解决方案:字符串模拟大数加法

既然无法用整型处理超长数字,直接在字符串层面模拟加法即可,同时自然保留前导零(或按需处理)。

1. 实现大数加法函数

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

// 大数加法,返回结果字符串(需手动free)
char* addStrings(const char* num1, const char* num2) {
    int len1 = strlen(num1);
    int len2 = strlen(num2);
    int max_len = len1 > len2 ? len1 : len2;
    // 结果最多比最长字符串多1位(进位)
    char* result = (char*)malloc(max_len + 2);
    if (!result) return NULL;

    int carry = 0;
    int i = len1 - 1, j = len2 - 1, k = 0;

    // 从低位到高位逐位相加
    while (i >= 0 || j >= 0 || carry > 0) {
        int digit1 = i >= 0 ? num1[i--] - '0' : 0;
        int digit2 = j >= 0 ? num2[j--] - '0' : 0;
        int sum = digit1 + digit2 + carry;
        carry = sum / 10;
        result[k++] = (sum % 10) + '0';
    }

    // 反转结果(因为是从低位开始存储的)
    for (int p = 0, q = k - 1; p < q; p++, q--) {
        char temp = result[p];
        result[p] = result[q];
        result[q] = temp;
    }
    result[k] = '\0';
    return result;
}

2. 修改链表求和逻辑

替换原代码中整型转换、反转的部分,直接用字符串加法处理:

struct ListNode *addTwoNumbers(struct ListNode * l1, struct ListNode * l2)
{
    char num1[500] = "";
    char num2[500] = "";

    // 拼接链表节点到字符串(保留所有前导零)
    struct ListNode *tmp = l1;
    while (tmp != NULL)
    {
        char c[2]; // 单个数字仅需2字节存储
        sprintf(c, "%d", tmp->val);
        strcat(num1, c);
        tmp = tmp->next;
    }

    tmp = l2;
    while (tmp != NULL)
    {
        char c[2];
        sprintf(c, "%d", tmp->val);
        strcat(num2, c);
        tmp = tmp->next;
    }
    printf("%s + %s\n", num1, num2);

    // 执行大数加法
    char* sum_str = addStrings(num1, num2);
    if (!sum_str) {
        exit(1); // 内存分配失败处理
    }
    printf("Sum: %s\n", sum_str);

    // 生成结果链表(保持原逻辑:将字符串逆序生成链表)
    struct ListNode *head = NULL;
    int len = strlen(sum_str);
    for (int i = 0; i < len; i++)
    {
        struct ListNode *n = malloc(sizeof(struct ListNode));
        if (n == NULL)
        {
            // 内存分配失败时,释放已分配资源
            while (head) {
                struct ListNode* next = head->next;
                free(head);
                head = next;
            }
            free(sum_str);
            exit(1);
        }
        n->val = sum_str[i] - '0';
        n->next = head;
        head = n;
    }

    // 释放资源
    free(sum_str);
    tmp = l1;
    while (tmp != NULL)
    {
        struct ListNode *next = tmp->next;
        free(tmp);
        tmp = next;
    }
    tmp = l2;
    while (tmp != NULL)
    {
        struct ListNode *next = tmp->next;
        free(tmp);
        tmp = next;
    }

    return head;
}

补充说明

  • 如果需要去掉结果字符串的前导零(比如00123转成123),可以在生成链表前遍历字符串,找到第一个非零字符后再处理;
  • 若链表本身是低位在前的存储结构(如LeetCode经典两数相加题),更高效的方式是直接在链表上逐位相加并处理进位,无需拼接成字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:59:49