Как превратить строку в 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;
}
Предоставленный ответ отвечает на вопрос, который вы задаете о ведущих нулях. Но у вас, кажется, есть вопросы о том, как складывать большие числа. Можете ли вы задать другой вопрос, иллюстрирующий то, что вы пытаетесь сделать, и алгоритм, которому вы пытаетесь следовать?
Мне нужно сделать с ним математику следующим образом: ``` str1 = "086568357" str2 = "678085897" // Перевернуть строки rstr1 = "753865680" rstr2 = "798580876" // Преобразовать их в длинные long_num1 = 753865680 long_num2 = 798580876 // и затем получаем сумму. sum = long_num1 + long_num2 ```, но начальный ноль удаляется, и это делает вычисления неправильными
Возможно, была бы уместна другая стратегия?
это то, что я пытаюсь сделать. Я пытаюсь решить это уже около 5 часов, но не могу понять.
Вам нужно будет перевернуть строку (работая с ней как с массивом char), прежде чем преобразовать ее в целое число. «Обратное» на самом деле не является арифметической операцией, поскольку оно зависит не только от того, что на самом деле представляет собой число, но и от того, как оно написано.
В качестве примера: скажем, у Алисы тринадцать яблок. Это можно записать как 13, или 013, или 0000013, но все они равны тринадцати. Что получится, если поменять местами количество яблок, которое есть у Алисы? У вас получится 31 (один), или 310, или 3100000? На этот вопрос нельзя ответить, просто зная, сколько у нее яблок. Таким образом, вы не можете решить эту проблему, оперируя long int (который представляет только число); вы должны использовать строку (которая представляет, как она написана).
Это не «каст». Это преобразование типов.
поэтому лучше всего преобразовать строку в строку, а затем преобразовать ее в длинное число.
ну, это решило сначала перевернуть строки, а затем преобразовать их в длинные, и код проходит 1556 случаев из 1558, я думаю, что с этим все в порядке. и, возможно, я попробую переключиться на Python, потому что я видел, как кто-то другой делал то же, что и я, в 15 строк.





Удалите начальный ноль ожидаемого результата. 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 ```, но начальный ноль удаляется, и это делает вычисления неправильными
Затем переверните строку перед выполнением (длинного) сложения. Или сделайте сложение, используя строки (см. ответ @chux-ReinstateMonica ниже) и не преобразовывайте их в длинные.
... получение чисел из двух связанных списков, преобразование их в длинные, чтобы я мог получить сумму...
Вместо преобразования в 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);
}
это сработало!! Большое спасибо!!
Ведущий ноль не имеет значения для длинного int. Это строго проблема форматирования для отображения - она не влияет на то, что на самом деле представляет собой длинный int. При желании вы можете добавить начальные нули в свой вывод. Целые числа являются числовыми типами; они делают числовые вещи. Начальный ноль не меняет числовое поведение типа. Если вы посмотрите на память, занимаемую типом long int, вы увидите, что он действительно включает нули для неиспользуемых битов в пределах размера типа.
printfпросто не включает начальные нули по умолчанию.