print a integer in c using putchar only - c

This is an old practice and I am trying to identify where i went wrong with my code: write a c program to print an integer using putchar only. I know one right way to do it is:
void printnumber(int n)
{
if (n < 0) {
putchar('-');
n = -n;
}
if (n == 0)
putchar('0');
if (n/10)
printnumber(n/10);
putchar(n%10 + '0');
}
I just want to know why my way of doing it does not work, though as I was trying to debug using step over, it looks there is no problem with my procedure, however, the code is printing some funny character. I thought it is because putchar() read the number as ascii value and print the character corresponding to ascii value, and maybe this is why in the code above, we are using putchar(n%10+'0'), so I tried to add '0' to all my putchar code, but it does not work properly. So here is my code and result without and with '0' when i=-123
void printnumber(int i)
{
if(i/10!=0)
{
putchar(i%10);
printnumber((i-i%10)/10);
}
else if((i/10==0) && (i%10!=0) && (i>0))
putchar(i%10);
else if((i/10==0) && (i%10!=0) && (i<=0))
putchar(-i%10);
}

The first version works like a charm for me.
Here's the function with main.
#include <stdio.h>
#include <stdlib.h>
void printnumber(int n)
{
if (n < 0) {
putchar('-');
n = -n;
}
if (n == 0)
putchar('0');
if (n/10)
printnumber(n/10);
putchar(n%10 + '0');
}
int main(int argc, char** argv)
{
int n = atoi(argv[1]);
printnumber(n);
printf("\n");
}
Here's some output:
~/Stack-Overflow/cpp>>./test-44
Segmentation fault
~/Stack-Overflow/cpp>>./test-44 10
10
~/Stack-Overflow/cpp>>./test-44 3456789
3456789
~/Stack-Overflow/cpp>>./test-44 -10
-10
~/Stack-Overflow/cpp>>./test-44 -95823
-95823
~/Stack-Overflow/cpp>>
PS. I am testing on Linux, using gcc 4.7.3.
Now about the second approach...
Adding '0' to the integer value in the call to putchar is absolutely needed.
In the first if block and the last else if block, you have take care of -ve numbers.
Printing 0 is still an issue.
In the first if block, recursion has to be before the print. Otherwise, you will end up printing the digits in the reverse order.
Here's what I came up with:
void printnumber(int i)
{
if(i/10!=0)
{
printnumber(i/10);
if ( i > 0 )
{
putchar(i%10 + '0');
}
else
{
putchar(-i%10 + '0');
}
}
else if((i/10==0) && (i%10!=0) && (i>0))
{
putchar(i%10 + '0');
}
else if((i/10==0) && (i%10!=0) && (i<=0))
{
putchar('-');
putchar(-i%10+'0');
}
}
PS. My version continues to have a problem with the number 0. It doesn't print anything.

if(i/10!=0)
{
putchar(i%10);
printnumber((i-i%10)/10);
}
If i < 0, then the first putchar() is in trouble no matter you + '0' or not.

Related

Program printing wrong output

Why is the following code printing !notreblo! instead of !notrebloH? Where is the ! coming from? I am trying to write a program that reverses an array and I am using the main function to test the rev_string function.
#include <stdio.h>
int main(void)
{
char s[11] = "Holberton!";
printf("%s\n", s);
rev_string(s);
printf("%s\n", s);
return (0);
}
void rev_string(char *s)
{
char new[500];
int count, newcount;
count = 0, newcount = 0;
while (*(s + count) != '\0')
{
*(new + count) = *(s + count);
count++;
}
count--;
while (count > 0)
{
*(s + newcount) = *(new + count);
count--;
newcount++;
}
}
The second while does not copy the first character, because the last character copied is at index 1. The condition tells it so: count > 0.
Change it to count >= 0.
(+1 for the famous "one-off" error. If I got 1 cent each time, I'll be a rich person.)
Notice your second while condition: while (count > 0). You aren't including your last character - e.g. if count == 3 (3 characters to reverse), you will only iterate twice - and your third character will not be written. You need to change the condition to while (count >= 0).
As a bonus, the function you are implementing is better known as strrev - and it can be implemented without an additional buffer.
Because you should change your second while condition to while (count >= 0)

Recursive print of binary number

I'm struggling to write a recursive way to print a binary number. Here is what I have so far:
int bin(unsigned char n)
{
if (n==0) {
return 0;
} else {
printf("%d", bin(n<<1));
}
}
bin(7)
What seems to be wrong with the logic above?
A few errors such as using << (shift up) instead of >> (shift down). Also not always returning something. I'm surprised the compiler didn't pull you up on that. You don't gain anything from a return value, So you may as well get rid of it.
A simple implementation could look like this. We need to have the wrapped function (bin_recur) to allow us to differentiate between 0 the input value and 0 which signifies its time to stop recursion.
#include <stdio.h>
void bin_recur(unsigned char n)
{
if (n > 0)
{
printf("%d", n & 1);
bin_recur(n >> 1);
}
}
void bin(unsigned char n)
{
if (n == 0)
{
printf("0\n");
} else
{
bin_recur(n);
printf("\n");
}
}
int main()
{
for(unsigned i = 0; i < 10; i++)
{
bin(i);
}
}
The fact that your bin function calls printf is not completely ideal. This is what's known as tight coupling and the function could be more reusable if it was not bound to how it is presented. Perhaps copying to a string is a good way or even using fprintf to print to a file.
Stopping when n is 0 is wrong.
This fails for the trivial case where n is 0 to start with.
What you really need to do is pass down a shift amount as a second argument and stop after 8 bits.
Using the return with value just gets in the way.
Here's some refactored code with a full diagnostic test:
#include <stdio.h>
void
bin2(unsigned char n,int shf)
{
if (shf <= 7) {
bin2(n,shf + 1);
printf("%d", (n >> shf) & 1);
}
}
void
bin(unsigned char n)
{
bin2(n,0);
}
int
main(void)
{
for (unsigned int chr = 0; chr <= 0xFF; ++chr) {
printf("%2.2X: ", chr);
bin((unsigned char) chr);
printf("\n");
}
return 0;
}
please add this lines to your code.
void binary(int n) {
if(n==0)
return;
binary(n/2);
printf("%d",n%2);
}
You need the print call to execute after the recursive function for this to work. Here's an example:
void bin(unsigned char n)
{
if (n > 1) bin(n>>1);
putchar(n&1 ? '1' : '0');
}
int main(void)
{
for (unsigned char i = 255; i; i--) {
printf("%d --> ", i), bin(i);
getchar(); // inspect element if you want
}
}
Link to running code here.

Recursive function to calculate successor of a numeric string

I want to write a recursive function which calculates Succ(‘2468’) = '2469'. ‘2468’ is a numeric string.
The exercice give me some predefined function such as last(ch), which returns the last caracter of a string, start(ch), returns ch without the last caracter, addEnd(ch, c), adds c at the end of ch and ask me to return a string as final result (i.e., suc("123")="124")
I tried this code but it works only for a string with 2 characters. If the length of my string is > 2, it doesn't work:
int successor (char*ch)
{
if (strlen (ch)==1)
return (int(*ch))+1);
else
return ((int(*ch))*10+successor(ch+1));}
There seems to be no need for multiplication or use of powers. Given the extra predefined functions you indicated were provided, I think the intention here was for a recursive way to express long addition with carry. I don't know C but here's an illustration in JavaScript that has very close syntax. I hope this helps.
function successor(s){
if (s.length == 1){
if (s == '9'){
return '10';
} else {
// Return the successor character,
// not sure how this looks in C.
return String.fromCharCode(
s.charCodeAt(0) + 1);
}
}
let rightmost = successor(last(s));
// No carry so just return
// the string with the last
// character incremented
if (rightmost != '10'){
return addEnd(start(s), rightmost);
// We have a carry so
// continue the recursion
} else {
return addEnd(successor(start(s)), '0');
}
}
function last(s){
return s.substr(-1);
}
function start(s){
return s.substr(0, s.length - 1);
}
function addEnd(s, c){
return s + c;
}
console.log(successor('2999'));
A key problem is this logic:
(int(*ch))*10+successor(ch+1)
the multiplication by 10 is insufficient for larger numbers. We need to multiply by a power of 10 and we already calculated that power but didn't hang onto it:
strlen (ch)
or more specifically:
strlen(ch) - 1
A complete solution:
#include <math.h>
#include <stdio.h>
#include <string.h>
#define digit(c) (c - '0')
int successor(char *string)
{
size_t power = strlen(string) - 1;
if (power == 0)
{
return digit(*string) + 1;
}
return digit(*string) * pow(10, power) + successor(string + 1);
}
int main() {
printf("%d\n", successor("2999"));
return 0;
}
OUTPUT
> ./a.out
3000
>
TODO
What happens if successor() is passed an empty string:
printf("%d\n", successor(""));
How can you modify the code to fix this? First decide what the function should return in this situation. What happens if successor() is passed a string that represents a number too large to be contained in an int:
printf("%d\n", successor("8589934592"));
How can you modify the code to fix this? Again, first decide what the function should return in this situation.

bitwise operation, printing of bits depends of which putchar is put first...?

I'm simply trying to print an unsigned int as bits, but it appears my code:
void checksWithOne(unsigned int userInput)
{
int i = 0, a = 0;
for (i = sizeof(int)*8-1; i >= 0; i--)
{
a = (userInput&(1<<i));
if (a==1)
{
putchar('1');
}
else
{
putchar('0');
}
}
printf("\n");
}
Only works if the if statement is changed as such (replacing 1s and 0s):
if (a==0)
{
putchar('0');
}
else
{
putchar('1');
}
It's beyond me as to why that is... any thoughts?
Thanks
Second code works because you prints '0' when a is == 0 else '1'. Accordingly in first code piece, if(a==1) should be if(a) that means print 1 if a is not 0 (Rremember every non-zero value is true in C).
The thing is a = (userInput & (1<<i)); is not always 1 but a can be a number that is either zero or a number in which only one bit is one (e.g. ...00010000)
The result of a = (userInput&(1<<i)) will be either 1<<i or 0, (not 1 or 0). So change:
if (a==1)
to:
if (a != 0)
and your code should work.

Base conversion using recursion

I'm working on an assignment and have it partially solved.
Currently I'm getting the correct output, only in reverse.
Here's the helper function I've implemented:
char int2char (int radix, int value) {
char c = '?';
if ((value >= 0 && value < radix) && (radix <= 36 && radix >= 2)){
if (value < 10){
c = value + 48;
}
else if (value >= 10 && value < 36) {
c = value + 55;
}
}
return c;
}
And the actual function I'm having difficulty with looks like this thus far:
void int2str (int radix, int value) {
int result = value % radix;
int division = value / radix;
char c;
c = int2char(radix, result);
putchar(c);
while (division > 0) {
return int2str(radix, division);
}
}
The first function is used to represent the digits 10-35 in hex. So if the modulus produces an 11, for example, I'm supposed to output a 'B'.
This is working great, except backwards! And I can't figure out how to reverse it. The biggest hitch is you can only use putchar() as an output. No strings, no arrays.
To further clarify, if I enter:
int2str 16 60
The output should be '3C', instead I'm getting 'C3'.
First off, your use of while is confusing, since there's a return in it. Replace that with if. The return is unnecessary, since the function will return on its own at the end.
Once you've done that, you can reverse the output by moving the putchar after the recursive call:
if (division > 0) {
int2str(radix, division);
}
putchar(c);
As a side note, return int2str(radix, division); doesn't make sense in this function anyway, since it's a void function, so there's nothing to return. If you did want to do this (you don't in this case), you would say:
somefunction();
return;
Also, this may be more clear if you used '0' and 'A' instead of 48 and 55:
if (value < 10){
c = value + '0';
}
else if (value >= 10 && value < 36) {
c = value - 10 + 'A';
}
result is the last digit, but you're printing it first. Drop the return from the recursive call and move the putchar to the end. Also, the while loop should be an if.
void int2str(int radix, int value) {
int lastdigit = value % radix;
int firstdigits = value / radix;
if (firstdigits) {
int2str(radix, firstdigits);
}
putchar(int2char(radix, lastdigit));
}
Try this
c = int2char(radix, result);
if (division > 0)
int2str(radix, division);
putchar(c);
Last call to int2str will print first digit while first call will print last digit.

Resources