У меня есть эта программа, которая пытается преобразовать строку символов в другую базу без использования atoi. Почему вывод не печатается в конце? Текст «Вывод:» печатается, но после него ничего нет.
Код, кажется, работает до этого момента. Я пошел дальше и добавил нулевой байт.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
void Int(char* numstring, int base) {
char *digitPtr = numstring;
char ans[100];
int decVal = 0;
int totalVal = 0;
int numDigits = 0;
// Go through the entire string to get the decimal value of the number.
while (*digitPtr != '\0') {
numDigits++;
digitPtr++;
}
// Now calculate decimal value of the string.
printf("before decimal value calc \n");
// *digitPtr = numstring;
int length = numDigits;
numDigits--;
printf("numDigits: %d \n", numDigits);
for (int i = 0; i < length; i++)
{
printf("calcuating the dec \n");
decVal = (*numstring - 48);
printf("dec Value: %d \n", decVal);
printf("power: %f \n", pow(10, numDigits));
totalVal = totalVal + decVal * pow(10, numDigits);
printf("totalVal %d \n", totalVal);
numDigits--;
numstring++;
}
//*digitPtr = numstring;
numDigits = length;
printf("totalVal %d \n", totalVal);
while (totalVal > 0) {
int remainder = totalVal % base;
printf("remainder: %d \n", remainder);
totalVal = totalVal / base;
ans[numDigits] = remainder;
numDigits--;
}
ans[99] = '\0';
printf("Output: %s \n", ans);
}
int main() {
Кроме того, использование numDigits
в качестве индекса выглядит неправильно. Например, если есть одна цифра, она будет сохранена в ans[1]
вместо ans[0]
. ans[99] = '\0';
также неверен, так как он помещает NUL в конец массива, а не в конец последовательности цифр - в результате после цифр появляется мусор, который printf
попытается проанализировать как часть строки.
В любом случае, если вы не делаете функцию в качестве домашнего задания, вы можете использовать strtol
Я получил уведомление о том, что вы сказали, что это не домашнее задание. (Но потом вы удалили комментарий) В этом случае вам действительно не нужно изобретать велосипед.
Да, это не домашняя работа, а «вызов», в котором вы не должны использовать эти функции.
В качестве общего примечания:(*numstring - 48);
Не используйте магические числа. Если вы имеете в виду '0'
, напишите '0'
не какое-то числовое значение, которое зависит от кодировки символов, и большинство людей должны сначала искать в диаграмме ASCII.
@Groo Хорошо, это что-то печатает .... но почему?
@BobBobsonTheThirdEsq.: Я не слишком много анализировал код, но так же, как вы вычли 48 (код ascii для «0») из символа ascii при преобразовании в числовое значение, вам придется добавить 48 при обратном преобразовании . Но есть несколько других ошибок с кодом, и я бы рекомендовал разделить этот код на две отдельные функции, а затем протестировать их по отдельности.
Он ничего не печатает, потому что вы присваиваете числовое значение остатка char
, но вы не учитываете, что числа начинаются с 48 (то есть '0'
) в таблице ASCII, поэтому вы должны добавить «начало point" к вашему остатку:
ans[numDigits] = remainder + '0';
Тем не менее, есть еще одна проблема: вы присваиваете длину входного значения numDigits
перед циклом while
, но длина числа, вероятно, не будет такой же, как длина числа в новой базе (например, Число 32 по основанию 10 состоит из двух цифр, а по основанию 2 — еще на четыре цифры). Решение может состоять в том, чтобы заставить numDigits
начинаться с 0, увеличивать его после каждой итерации и печатать строку символ за символом в обратном порядке. В качестве альтернативы математический подход для получения количества цифр числа в пользовательской базе прибавляет единицу к округленному логарифму числа в пользовательской базе. Для этого вы можете использовать свойства логарифма, поскольку стандартные библиотеки C предоставляют журналы только в базе 2, e и 10.
numDigits = (int)(floor(log(totalVal) / log(base) + 1);
Следуя этому подходу, вам не нужно менять свой цикл, и вы можете распечатать результат в виде строки.
Обратите внимание, что вы не должны устанавливать ans[99]
на '\0';
, так как между преобразованным числом и концом строки может быть мусор; вместо этого вы должны установить его на numDigits
. Вы также можете инициализировать ans
значением 0
(что является числовым представлением \0
), чтобы забыть о ручной установке терминатора.
ans[numDigits] = remainder + '0'