Как преобразовать строку в Long-int в C?

Как превратить строку в C в длинное целое число, не удаляя начальный нуль?

Я использовал обе функции sscanf() и strtol(), но обе они удаляют начальный ноль, как будто это пробел. Я пробовал

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

   int main()
   {
       char *num = "09999999991";

       long n = strtol(num, NULL, 10);;

       printf("%ld\n", n); 
    
       /*
           Output: 9999999991 
           Expected: 09999999991
       */ 
   }

Я изначально получаю числа из двух связанных списков, преобразовывая их в длинные, чтобы я мог получить сумму и сделать новый связанный список из суммы, как показано ниже.

    struct ListNode *addTwoNumbers(struct ListNode * l1, struct ListNode * l2)
    {
        // make two string to hold the nums
        char num1[500] = "";
        char num2[500] = "";

        long long n1, n2, sum, reverse1 = 0, reverse2 = 0, remainder;

        // get the first num
        struct ListNode *tmp = l1;
        while (tmp != NULL)
        {
            char c[600];
            sprintf(c, "%lld", tmp->val);
            strcat(num1, c);
            tmp = tmp->next;
        }

        // get the second num
        tmp = l2;
        while (tmp != NULL)
        {
            char c[600];
            sprintf(c, "%lld", tmp->val);
            strcat(num2, c);
            tmp = tmp->next;
        }
        printf("%s + %s\n", num1, num2);

        // cast to int
        n1 = strtol(num1, NULL, 10);
        n2 = strtol(num2, NULL, 10);
        printf("%lld + %lld\n", n1, n2);

        // reverse the numbers
        while (n1 != 0)
        {
            remainder = n1 % 10;
            reverse1 = reverse1 * 10 + remainder;
            n1 /= 10;
        }
        while (n2 != 0)
        {
            remainder = n2 % 10;
            reverse2 = reverse2 * 10 + remainder;
            n2 /= 10;
        }

        printf("%lld + %lld\n", reverse1, reverse2);

        // get the sum
        sum = reverse1 + reverse2;

        printf("%ld\n", sum);
        char value[500];
        sprintf(value, "%ld", sum);

        struct ListNode *head = NULL;
        for (int i = 0, len = strlen(value); i < len; i++)
        {
            struct ListNode *n = malloc(sizeof(struct ListNode));
            if (n == NULL)
            {
                exit(1);
            }

            n->val = value[i] - '0';
            n->next = NULL;

            n->next = head;
            head = n;
        }

        // free memory
        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;
    }

Ведущий ноль не имеет значения для длинного int. Это строго проблема форматирования для отображения - она ​​не влияет на то, что на самом деле представляет собой длинный int. При желании вы можете добавить начальные нули в свой вывод. Целые числа являются числовыми типами; они делают числовые вещи. Начальный ноль не меняет числовое поведение типа. Если вы посмотрите на память, занимаемую типом long int, вы увидите, что он действительно включает нули для неиспользуемых битов в пределах размера типа. printf просто не включает начальные нули по умолчанию.

h0r53 11.07.2023 19:07

Предоставленный ответ отвечает на вопрос, который вы задаете о ведущих нулях. Но у вас, кажется, есть вопросы о том, как складывать большие числа. Можете ли вы задать другой вопрос, иллюстрирующий то, что вы пытаетесь сделать, и алгоритм, которому вы пытаетесь следовать?

jxh 11.07.2023 20:59

Мне нужно сделать с ним математику следующим образом: ``` str1 = "086568357" str2 = "678085897" // Перевернуть строки rstr1 = "753865680" rstr2 = "798580876" // Преобразовать их в длинные long_num1 = 753865680 long_num2 = 798580876 // и затем получаем сумму. sum = long_num1 + long_num2 ```, но начальный ноль удаляется, и это делает вычисления неправильными

Blnd-hussen 11.07.2023 21:03

Возможно, была бы уместна другая стратегия?

Neil 11.07.2023 21:13

это то, что я пытаюсь сделать. Я пытаюсь решить это уже около 5 часов, но не могу понять.

Blnd-hussen 11.07.2023 21:20

Вам нужно будет перевернуть строку (работая с ней как с массивом char), прежде чем преобразовать ее в целое число. «Обратное» на самом деле не является арифметической операцией, поскольку оно зависит не только от того, что на самом деле представляет собой число, но и от того, как оно написано.

Nate Eldredge 11.07.2023 22:19

В качестве примера: скажем, у Алисы тринадцать яблок. Это можно записать как 13, или 013, или 0000013, но все они равны тринадцати. Что получится, если поменять местами количество яблок, которое есть у Алисы? У вас получится 31 (один), или 310, или 3100000? На этот вопрос нельзя ответить, просто зная, сколько у нее яблок. Таким образом, вы не можете решить эту проблему, оперируя long int (который представляет только число); вы должны использовать строку (которая представляет, как она написана).

Nate Eldredge 11.07.2023 22:22

Это не «каст». Это преобразование типов.

user207421 12.07.2023 02:15

поэтому лучше всего преобразовать строку в строку, а затем преобразовать ее в длинное число.

Blnd-hussen 12.07.2023 08:52

ну, это решило сначала перевернуть строки, а затем преобразовать их в длинные, и код проходит 1556 случаев из 1558, я думаю, что с этим все в порядке. и, возможно, я попробую переключиться на Python, потому что я видел, как кто-то другой делал то же, что и я, в 15 строк.

Blnd-hussen 12.07.2023 13:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
77
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Удалите начальный ноль ожидаемого результата. long хранит число 9999999991. Токен 09999999991, кстати, имеет недопустимую восьмеричную константу.

Если вы хотите отформатировать число, дополненное цифрами от 0 до 11, вы можете использовать строку формата "%011ld\n". Поскольку у вас уже есть строка, вы можете сделать это во время выполнения следующим образом:

#include <string.h>
// ...
printf("%0*ld\n", (int) strlen(num), n);

да, но я не хочу печатать число, которое мне нужно для математических операций, например так: ``` str1 = "086568357" str2 = "678085897" // Переворачиваем строки rstr1 = "753865680" rstr2 = "798580876" // Преобразуем их в длинные long_num1 = 753865680 long_num2 = 798580876 // и затем получим сумму sum = long_num1 + long_num2 ```, но начальный ноль удаляется, и это делает вычисления неправильными

Blnd-hussen 11.07.2023 20:54

Затем переверните строку перед выполнением (длинного) сложения. Или сделайте сложение, используя строки (см. ответ @chux-ReinstateMonica ниже) и не преобразовывайте их в длинные.

Allan Wind 13.07.2023 00:11
Ответ принят как подходящий

... получение чисел из двух связанных списков, преобразование их в длинные, чтобы я мог получить сумму...

Вместо преобразования в long, добавления и обратного преобразования в строку рассмотрите возможность простого добавления содержимого строки.

Ниже показано, как найти потенциально необходимый размер строки, выделить, а затем сложить, точно так же, как мы учились в наши ранние школьные годы, находит сумму по одной цифре за раз. Начнем с младшей значащей цифры.

// Untested illustrative code

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

// Return an allocated string of the sum of the strings.
// Return NULL on problems: out-of-memory, non-numeric text.
char* string_sum(const char *a, const char *b) {
  const char *s;

  // Test for digits only and find length
  for (s = a; *s; s++) {
    if (!isdigit(*(const unsigned char* )s)) {
      return NULL;
    }
  }
  size_t a_len = (size_t) (s - a);

  for (s = b; *s; s++) {
    if (!isdigit(*(const unsigned char* )s)) {
      return NULL;
    }
  }
  size_t b_len = (size_t) (s - b);

  // Allocate 
  size_t c_len = a_len > b_len ? a_len : b_len;
  c_len++; // +1 for potential carry.
  size_t c_size = c_len + 1 /* null character */;
  char *c = malloc(c_size);
  if (c == NULL) {
    return NULL;
  }
  c[c_len] = '\0';

  // Add digits, starting with least.
  int carry = 0;
  while (a_len > 0 || b_len > 0 || carry) {
    int sum = carry;
    if (a_len > 0) {
      sum += a[--a_len] - '0';
    }
    if (b_len > 0) {
      sum += b[--b_len] - '0';
    }
    c[--c_len] = (char) ('0' + sum % 10);
    carry = sum / 10;
  }

  // Adjust for carry and return.
  return memmove(c, c + c_len, c_size - c_len);
}

это сработало!! Большое спасибо!!

Blnd-hussen 13.07.2023 11:26

Другие вопросы по теме