Palindromic numbers in C, string error - c

New to C. Trying to write program that prints out palindromic numbers < 1 million.
Prints out jibberish. Have I made an error with strings?
int decimal_pali(int x)
{
int digits=0;
int num=x;
char D[7];
while(num>0)
{
D[digits]=num%10;
digits+=1;
num/=10;
}
D[digits]='\0';
num=atoi(D);
if(num == x)
{
return 1;
}
return 0;
}

Your mistake lies here:
D[digits]=num%10;
It should be
D[digits] = num%10 + '0';
num % 10 will result in a number between 0 and 9 inclusive but since you are working with characters, you need to get the ASCII value of the digit. If you have a look at the ASCII table, you'll find that in order to achieve what you want, you need to add the ASCII value of '0' (48) to the value to get the correct character.

Curiosity wouldn't let me resist the "more than one base" thing, though I doubt the result has any (non-trivial) number-theoretic significance. Anyway, here's the code, and a sample run below that...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( int argc, char *argv[] ) {
int n1 = ( argc>1? atoi(argv[1]) : 1 ),
n2 = ( argc>2? atoi(argv[2]) : 999 ),
b1 = ( argc>3? atoi(argv[3]) : 10 ),
b2 = ( argc>4? atoi(argv[4]) : 10 );
int n=n1, b=b1, ispal();
char *itoa();
for ( n=n1; n<=n2; n++ ) {
for ( b=b1; b<=b2; b++ ) if ( !ispal(n,b) ) goto next_n;
printf("%10d(base10)",n);
for ( b=b1; b<=b2; b++ ) printf(" = %s(%d)", itoa(n,b),b);
printf("\n");
next_n: ; }
} /* --- end-of-function main() --- */
int ispal ( int i, int base ) {
char *itoa(), *a=itoa(i,base);
int answer=0, k=0,n=strlen(a);
if ( n > 1 ) {
for ( k=0; k<n/2; k++ )
if ( a[k] != a[n-k-1] ) goto end_of_job;
answer = 1; }
end_of_job: return ( answer );
} /* --- end-of-function ispal() --- */
char *itoa ( int i, int base ) {
static char a[99], digits[99] = /* up to base 65 */
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$*";
int n = 0;
while ( 1 ) {
a[n++] = digits[i%base];
if ( (i/=base) < 1 ) break; }
a[n] = '\000';
return ( a );
} /* --- end-of-function itoa() --- */
I called it palinum.c, and a typical run gives...
bash-4.3$ ./palinum 1 9999999 3 4
10(base10) = 101(3) = 22(4)
130(base10) = 11211(3) = 2002(4)
11950(base10) = 121101121(3) = 2322232(4)
175850(base10) = 22221012222(3) = 222323222(4)
749470(base10) = 1102002002011(3) = 2312332132(4)
1181729(base10) = 2020001000202(3) = 10200200201(4)
showing just a few numbers between 1 and 10million that are "palindromic" in both base 3 and base 4. The few other tests I did showed nothing simultaneously palindromic in three consecutive bases. But the program's easily changed to permit any set of (non-consecutive) bases. (For a less trivial programming challenge, try multiple threads for several n's at a time.)

Related

Why my number to string converter keeps returning 000?

I have a issue with my number to string implemention. For some reason I keep getting 000 on my terminal even though. I couldn't find a solution, what is the potantial issue here?
Im now sure my code is broken but don't really see the problem.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* public domain code feel free to use as what you wish, no warranties given*/
char finddigits(unsigned n) {
char base = 6;
unsigned tester = 100000;
while(base % tester != 0) {
base--;
/* inefficient but works for now */
switch(tester) {
case 100000:
tester = 10000;
break;
case 10000:
tester = 1000;
break;
case 1000:
tester = 100;
break;
case 100:
tester = 10;
break;
case 10:
tester = 1;
break;
}
}
return base;
}
char* num2str(unsigned n) {
char size = finddigits(n);
char* tempbuf = malloc(size);
*tempbuf = 48 + (n / pow(10, size));
for(unsigned int i = 1; i < size; i++)
*(tempbuf + i) = 48 + (n % (10 * i));
return tempbuf;
}
int main(int argc, char* argv[]) {
int numbr = 210;
printf("%s \n", num2str(numbr));
/* expected 210 on string got 000 */
return 0;
}
You just want num2str to return the digit string for n.
A few issues:
finddigits is supposed to calculate the number of digits in n. But, [if it works at all], it uses an algorithm I've never seen.
finddigits isn't needed in num2str as num2str can be [much] simpler by filling the buffer in the reverse direction.
num2str is too complicated.
Calling num2str from printf leaks memory from the num2str call to malloc
Here's a refactored version:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
char
finddigits(unsigned n)
{
int count = 0;
if (n == 0)
count = 1;
for (; n != 0; n /= 10, ++count);
return count;
}
char *
num2str(unsigned n)
{
static char buf[100];
char *dst = &buf[sizeof(buf) - 1];
// add string terminator
*dst-- = 0;
// we must always output a 0
if (n == 0)
*dst-- = '0';
// work backwards in the array
for (; n != 0; n /= 10, --dst)
*dst = (n % 10) + '0';
// point to first digit in string
dst += 1;
return dst;
}
void
dotest(unsigned n)
{
printf("n=%u '%s'\n",n,num2str(n));
}
int
main(int argc, char *argv[])
{
dotest(210);
dotest(0);
dotest(12345);
return 0;
}
Here's the program output:
n=210 '210'
n=0 '0'
n=12345 '12345'
The computer does what you told it to do, which is to say, it does complete nonsense.
finddigits(210) returns 1, because 6 % 100000 isn't 0 (it's 6), 5%10000 isn't 0 (it's 5), 4 % 1000 isn't 0 (it's 4), 3 % 100 isn't 0 (it's 3), 2 % 10 isn't 0 (it's 2), but 1 % 1 is 0 so the loop stops and the function returns 1.
Then, num2str allocates 1 byte. In this 1 byte, it sets the first byte to 48 + (210 / 10) which is 69, ASCII code for the letter E. Since size is 1 the loop doesn't run at all and num2str returns this allocation. When you print it, it prints the letter E - possibly with more gibberish after it since the string is not terminated, although for me it just printed E.
I have no idea how you managed to get 000.
You need to write code that tells the computer to do what you want it to do. When you can't get it to do what you want it to, for one part of the code, don't just skip that part of the code and go onto the next one. It all has to be right or it won't work.
Mathematics is also "public domain". Here are two versions of one of your functions, shown with a main() that tests both versions with several values.
Don't convert a signed integer value to unsigned for no particular reason. If you need/want the absolute value of a (possibly) negative number, C provides a function to achieve that.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int finddigits1( int n ) {
int count = n == 0; // ensure 0 is counted as 1 digit
while( n ) count++, n /= 10;
return count;
}
int finddigits2( int n ) {
// log of zero is undefined
return ( n == 0 ) ? 1 : (int)log10(abs(n))+1;
}
char *num2str( int n, char buf[] ) {
printf( "finddigits1( %d ) counted %d\n", n, finddigits1( n ) );
printf( "finddigits2( %d ) returns %d\n", n, finddigits2( n ) );
strcpy( buf, "Hello world!" ); // Left as an exercise to fix your own code
return buf; // returning allows direct usage by caller
}
int main() {
int tests[] = { 123, -123, 0, 100, 54321 };
char buf[ 30 ]; // better to pass large buffer to function than use malloc()
for( int i = 0; i < sizeof tests/sizeof tests[0]; i++ ) {
int n = tests[i];
printf( "n = %d '%s'\n", n, num2str( n, buf ) );
}
return 0;
}
finddigits1( 123 ) counted 3
finddigits2( 123 ) returns 3
n = 123 'Hello world!'
finddigits1( -123 ) counted 3 // NB: Account for negative sign!
finddigits2( -123 ) returns 3
n = -123 'Hello world!'
finddigits1( 0 ) counted 1
finddigits2( 0 ) returns 1
n = 0 'Hello world!'
finddigits1( 100 ) counted 3
finddigits2( 100 ) returns 3
n = 100 'Hello world!'
finddigits1( 54321 ) counted 5
finddigits2( 54321 ) returns 5
n = 54321 'Hello world!'
If you're trying to convert a number to a string, why not just use sprintf()?
See here:
How to convert an int to string in C?

How to calculate how many times a function is inside another function, for example g(9) inside g(k)

I am performing an activity, which is based on the recursive function, but I cannot understand how to put a part in code format. The code is this :
#include <stdio.h>
int count;
int g( int x ) {
count++;
if ( x == 0 )
return 2;
if ( x <= 2 )
return x * x;
if ( x <= 5 )
return x * g( x - 1 );
return (g( x - 3 ) + g( x - 2 ) );
}
int main () {
int k = 15;// random number
count = 0;
printf( " g(%d) = %d\n", k, g( k ) );
printf( " count: %d\n", count);
printf( " g(9) appeared : %d time(s) inside g(%d)",...,k);// in this space would be the other variable
return 0;
}
What I don't understand is how to calculate how many times, for example g(9), appears inside g(k). I've already made some attempts, but it never arrives at what is really requested. Thanks in advance

Recursive program for counting 1 bits in integer

I wrote an iterative program that counts of the amount of 1s in the binary of an integer given in argv[1], my iterative version worked fine but I'm having trouble figuring out how to make the function recursive.
I've tried changing the function with an if statement
#include <stdio.h>
#include <stdlib.h>
int bitcount( int x ) {
unsigned int count = 0 ;
count += x & 1;
x >>= 1 ;
if ( x > 0 ) {
bitcount( x ) ;
}
return count ;
}
int main( int argc, char *argv[] ) {
int b ;
b = atoi( argv[1] ) ;
b = bitcount ( b ) ;
printf( "%d\n", b ) ;
return 0 ;
}
My iterative program gave me the correct answer, but this program will print 1 no matter what number I use.
The problem is that you're not using the returned value of your bitcount function. Change
bitcount( x ) ; for count += bitcount( x ) ;

Run-Time Check Failure #2 - Stack around the variable 'd' was corrupted. (C programming under Visual Studio)

Hello I am new here and programming in C. I didn't want to ask something that you may consider simple but I have asked my classmates and even my programming teacher to see if they can find the error but until today they couldn't find it (them).
But first let me describe what I know, it says:
"Run-Time Check Failure #2 - Stack variable "d" (and sometimes m and
other y) was corrupted ".
I made my job trying to debug it but the problem is always showed on the last codeline (of the main body), so I couldn't find exactly where the problem is, here I attach the code, and I would be very happy if you find the problem and explain me the reason why I get it (to don't repeat the same mistakes in future) =D.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* Type Declaration */
#define true 1
#define false 0
typedef char boolean;
/* Functions declaration */
boolean test( short int d, short int m, long int y );
boolean nextday( short int d, short int m , long int y );
int main( void )
{
/* Variables initialization */
short int d = 0, m = 0;
long int y = 0;
do {
/* Data by user*/
printf( "Ingrese el numero de año: " );
scanf( "%ld", &y );
} while ( y < 0 );
do {
printf( "Ingrese el numero de mes: " );
scanf( "%d", &m );
} while ( m < 1 || m > 12 );
do {
printf( "Ingrese el numero de dia: " );
scanf( "%d", &d );
} while ( d < 01 || ( test( d, m, y ) == false ) ); // If the data is wrong then re-type the data
// If the nextday function return value is true then the next day is 01, if not just sum a day
if ( nextday ( d, m, y ) == true ) {
d = 01;
// If we start a new year the new month must be 01-01-01.
if ( m == 12 ) {
m = 01;
y++;
}
// Just increase the month for any other month
else {
m++;
}
}
else {
d++;
}
printf( "Mañana será: %d-%d-%ld\n", d, m, y );
return 0;
}
boolean test( short int d, short int m, long int y ){
int max;
switch(m) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
max = 31;
break;
case 4:
case 6:
case 9:
case 11:
max = 30;
break;
case 2:
if ( y % 400 == 0 ){
max = 29;
}
else if ( y % 100 == 0 ){
max = 28;
}
else if ( y % 4 == 0 ){
max = 29;
}
else {
max = 28;
}
break;
}
if ( d <= max ){
return true;
}
else {
return false;
}
}
boolean nextday( short int d, short int m, long int y ) {
boolean x;
// If it's 28-02 in a secular year * 4 then it's a leap-year. (so it has 29 days)
if ( m == 2 && d == 28 && y % 400 == 0 ) {
x = false;
}
// If it is an end of century but it isn't 4 multiply then it only has 28 days.
else if ( m == 2 && d == 28 && y % 100 == 0 ) {
x = true;
}
// If it just a leap year it has 29 days.
else if ( m == 2 && d == 28 && y % 4 == 0 ) {
x = false;
}
//If it's the last day of February and it's a leap year.
else if ( m == 2 && d == 29 && y % 4 == 0 ){
x = true;
}
// If we are in the end of the month.
else if ( ( d == 30 && ( m == 4 || m == 6 || m == 9 || m == 11 ) ) ||
d == 31 ) {
x = true;
}
// Then if it is another day just sum a day
else {
x = false;
}
return x;
}
You need to use:
scanf( "%hd", &m );
scanf( "%hd", &d );
since they are short int's.
Using "%d" you are basically loading an int size variable in a small int storage space.
An int is usually 4 bytes while small int is 2 bytes.
scanf( "%d", &m );
%d means "this argument points to an int." You are providing a pointer to a short int. Either use %hd (for short int) or, preferably, change m to type int (why bother with short int here?).

Ways optimize my recursive maze solver?

I have developed the following C program to find all possible paths out off a maze. And it has to go through each room in the maze. That is why the '54' is hard coded at the minute because for the 8*7 array I am passing in there are 54 open rooms. I will work this out and pass it dynamically when I am re-writing. However I am looking for some help in how to make the code more efficient - it finds over 300,000 possible paths to complete the maze I am passing in but it ran for almost an hour.
#include <stdio.h>
#define FALSE 0
#define TRUE 1
#define NROWS 8
#define MCOLS 7
// Symbols:
// 0 = open
// 1 = blocked
// 2 = start
// 3 = goal
// '+' = path
char maze[NROWS][MCOLS] = {
"2000000",
"0000000",
"0000000",
"0000000",
"0000000",
"0000000",
"0000000",
"3000011"
};
int find_path(int x, int y, int c, int *t);
int main(void)
{
int t = 0;
if ( find_path(0, 0, 0, &t) == TRUE )
printf("Success!\n");
else
printf("Failed\n");
return 0;
}
int find_path(int x, int y, int c, int *t)
{
if ( x < 0 || x > MCOLS - 1 || y < 0 || y > NROWS - 1 ) return FALSE;
c++;
char oldMaze = maze[y][x];
if ( maze[y][x] == '3' && c == 54)
{
*t = *t+1;
printf("Possible Paths are %i\n", *t);
return FALSE;
}
if ( maze[y][x] != '0' && maze[y][x] != '2' ) return FALSE;
maze[y][x] = '+';
if ( find_path(x, y - 1, c, t) == TRUE ) return TRUE;
if ( find_path(x + 1, y, c, t) == TRUE ) return TRUE;
if ( find_path(x - 1, y, c, t) == TRUE ) return TRUE;
if ( find_path(x, y + 1, c, t) == TRUE ) return TRUE;
maze[y][x] = oldMaze;
return FALSE;
}
First of all I don't see any base condition for the function to return TRUE, it only returns TRUE on calling itself recursively witch is to say it will the result will allways print Failed (I thought recursion had to have a base condition that when finding success will propagate upwards..)
Secondly can you please explain the values in the boxes? as in 0,1,2 and 3? Is 3 the end of the maze or?...

Resources