2014-01-30 5 views
1

Я пытаюсь напечатать целые числа в консоли на C с несколькими ограничениями, наиболее значительным из которых является то, что я могу писать только отдельные символы для консоль следующим образом:Печать целых чисел в виде символов (без массивов/printf/etc ...)

void my_char(char ch) 
} 
    write(1, &ch, 1); 
} 

Другие ограничения включают NO предопределенные методы (printf, log и т. д.). Нет рекурсии. Наконец, я НЕ могу создать массив.

До сих пор я придумал метод, который отлично печатает цифры ... назад.

int main() 
{ 
    int i = -345320; 
    my_int(i); 
    return 0; 
} 

void my_int(int x) 
{ 
    char *a; 
    int n; 

    if(x < 0) 
    { 
      x = x * -1; 
      my_char('-'); 
    } 

    while(x) 
    { 
      n = x % 10; 
      a = (char*)&n; 
      my_char(*a + 48); 
      x /= 10; 
    } 
} 

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

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

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

+0

Попробуйте рекурсию и распечатайте цифры после рекурсивного шага. – ooga

+0

Моя ошибка; Я также избегаю рекурсии. Обновлено, чтобы упомянуть об этом. – Elijah

+1

Чтобы сделать его более компактным, вы можете избавиться от n и a и просто использовать эту строку в цикле while 'my_char (x% 10 + '0');'. – ooga

ответ

1
void my_int(int x) 
{ 
    int n; 
    int copy; 
    char digit; 

    // handle 0 
    if (!x) 
    { 
     my_char('0'); 
     return; 
    }  

    // emit sign 
    if(x < 0) 
    { 
     x = x * -1; 
     my_char('-'); 
    } 

    // count base-10 digits in x, store 10^n in n 
    n = 1; 
    copy = x/10; // shorten loop by 1 iteration 
    while (copy) 
    { 
     n *= 10; 
     copy /= 10; 
    } 

    // 'n' is now a digit selector 
    while (n) 
    { 
     digit = x/n; 
     my_char(digit + '0'); // print the most significant digit 
     x -= digit*n; // remove the most significant digit from x 
     n /= 10; 
    } 
} 
+0

Похоже, что @ooga высказала эту идею как комментарий незадолго до того, как я отправил свой ответ. Обратите внимание, что я изменил тип «n» на «char» (хотя, как указывал оога, вы можете обойтись без него целиком.) –

+0

Тем не менее, все же печатает номер назад. :( – ooga

+0

О-о-о! Конечно. :) –

2

Это должно сделать трюк. Он печатает целые числа вперед .:

void my_int(int x) 
{ 
    int temp = 0; 
    int divFactor = 10; 

    if(x==0) 
    { 
     my_char('0'); 
     return; 
    } 

    if(x < 0) 
    { 
      x = x * -1; 
      my_char('-'); 
    } 
    temp = x; 
    while((temp /= 10) > 10) {divFactor *= 10;} 

    for(;divFactor > 0;divFactor /= 10) 
    { 
     temp = x; 
     temp /= divFactor; 
     my_char(temp + '0'); 
     x -= divFactor * temp; 
    } 
    printf("\n done!"); 
} 


int main() 
{ 
    int i = -1234001; 
    my_int(i); 
    return 0; 
} 
+0

Я предлагаю перерыв вместо флага. – ooga

+0

Хмммм, не работает для 12345. – ooga

+0

Вы правы по обоим пунктам. Я исправил '12345' и изменил свой флаг на перерыв. – George

2

Это общее (уродливое!) Решение, соответствующее вашим ограничениям. Он использует идею, которую я дал в комментарии выше. Он предполагает 32-битные ints.

void my_int(int x) { 
    int n = 1000000000; 
    if (x == 0) { 
     my_char('0'); 
     return; 
    } 
    if (x == INT_MIN) { // INT_MIN is in limits.h 
     my_char('-'); my_char('2'); my_char('1'); 
     my_char('4'); my_char('7'); my_char('4'); 
     my_char('8'); my_char('3'); my_char('6'); 
     my_char('4'); my_char('8'); 
     return; 
    } 
    if (x < 0) { 
     x *= -1; 
     my_char('-'); 
    } 
    while (n > x) n /= 10; 
    while (n != 0) { 
     my_char(x/n % 10 + '0'); 
     n /= 10; 
    } 
} 
+0

Это действительно кажется относительно надежным решением. Его нужно изменить, чтобы печатать конечные/внутренние 0 (простое изменение), но оно выглядит как разумный подход. – Elijah

+0

Arrghh! Я забыл отстающие нули! Одна секунда ... – ooga

+0

Хорошая проверка на INT_MIN. –

Смежные вопросы