runtime error SIGSEGV in c code on spoj for PALIN - c

A positive integer is called a palindrome if its representation in the decimal system is the same when read from left to right and from right to left. For a given positive integer K of not more than 1000000 digits, write the value of the smallest palindrome larger than K to output. Numbers are always displayed without leading zeros.
first i tried to save all the palindromes and then check for printing the number.
#include<stdio.h>
int array[2000],index=0;
long long n;
void savepalindrome()
{
long long lim=1000000;
long long i=1;
for(i=1;i<lim;i++)
{
if(checkpalindrome(i)==1) {
array[index]=i; index++;
}
}
}
int checkpalindrome(long long i) {
long long reverse=0, rem,temp;
temp=i;
while(temp!=0)
{
rem=temp%10;
reverse=reverse*10+rem;
temp/=10;
}
if(reverse==i) return 1;
else return 0;
}
int main() {
int t;
scanf("%d",&t);
savepalindrome();
while(t--) {
scanf("%d",&n);
index=0;
while(array[index]<=n) {
index++;
}
if(index<=1998) printf("%d\n",array[index]);
}
}

though if long long int is not capable of storing 1000000 digit number it will overflow in long long int's range.i think your index is going out of array bound.it seems only reason for SIGSEGV. SIGSEGV is sent to a process only if it accesses a memory location that is not valid.

Related

How do I have user input a long and then print that long accurately in C?

I am trying to create a program that has the user input a credit card sized number for the CS50 problem set 1.
After prompting the user to enter in the card number, I wrote a print function to make sure that I have the correct number stored. However, the output is always a number that is way off from the number I input. I have messed around trying to change the long to a long long or a long long int.
What should I try to get my code to correctly store the number I input?
Code:
#include<stdio.h>
#include<cs50.h>
int question(void);
int main(void)
{
long n = question();
printf("%ld\n", n);
}
int question(void)
{
long n;
do {
n = get_long("Number: ");
} while (n < 1000000000000 || n > 9999999999999999);
return n;
}
Output:
$ ./credit
Number: 1234567890123456
1015724736
Even though you are saving a long in n, your function is returning an int.
Just changing the return type will do the trick.
#include<stdio.h>
#include<cs50.h>
long question(void);
int main(void)
{
long n= question();
printf("%ld\n", n);
}
long question(void)
{
long n;
do
{
n = get_long("Number: ");
}
while (n < 1000000000000 || n > 9999999999999999);
return n;
}

Why does C outputs gibberish results when operation on an integer greater than 10 digits?

The code given below works fine up-to 10 digits with (int data-type) , but for numbers exceeding 10 digits it failed , so i tried unsigned long long int. But now my output is fixed to 15 , idk why? Consider me very new to C , i have mediocre python background though!
I am using gcc (Ubuntu 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609
#include <stdio.h> //Get number of digits in a int
unsigned long long int get_len();
void main() {
unsigned long long int num;
printf("Enter the number:");
scanf("%d",&num);
printf("\nThe length of number is is: %d \n",get_len(num));
}
unsigned long long int get_len(unsigned long long int z) {
unsigned long long int i = 1;
while (1) {
if ((z/10) > 1) {
//printf("Still greater than 1");
i++;
z = z/10;
continue;}
else {
return(i+1);
break;}}}
You have used wrong format specifier. it would be scanf("%llu",&num);
Using the wrong format specifer in scanf is undefined behavior.
Apart from what is being mentioned, your length finding logic is wrong in that it will fail for single digit numbers and also for multidigit one.
For 1 it will return number of digits 2 and similarly for other numbers. (like for 12 it will return 3).
For larger numbers you will have options of opting an library (big number processing) or write one of as you need.
I would scan the numbers like this
if( scanf("%llu",&num) != 1) { /* error */}. More clearly check the return value of scanf.
Here's another implementation. This fixes a few issues:
Main return type must be int.
unsigned int is more than sufficient as get_len() return type.
unsigned int and unsigned are the same. Also unsigned long long int can be stripped of int.
#include <stdio.h>
unsigned get_len();
int main()
{
unsigned long long num;
printf("Enter the number: ");
scanf("%llu", &num);
printf("\nThe length of number is: %u\n", get_len(num));
}
unsigned get_len(unsigned long long z)
{
return (z / 10 > 0) ? get_len(z / 10) + 1 : 1;
}

How to increase th range of integers in C?

I tried to solve the Small Factorial problem on SPOJ and got 'Wrong answer'. I wrote the following code :
#include <stdio.h>
int main() {
int t,i, num;
unsigned long long int fact=1;
scanf ("%d", &t);
while (t-- >0) {
fact=1;
scanf ("%d", &num);
for (i=num; i>0; i--) {
fact*=i;
}
printf ("%llu\n",fact);
}
return 0;
}
This code is not finding factorial for large inputs like 100. What are the changes required?
In C and C++ you have the maximum allowed range from -2^63+1 to +2^63-1 which is for long long data type. As you can see this range is still too small to store >20 digits.
You have to use a char array to store single digit per array index.
one way to do this in C++:
#include<stdio.h>
#include<iostream>
int main()
{
int t;
char a[200]; //array will have the capacity to store 200 digits.
int n,i,j,temp,m,x;
scanf("%d",&t); //enter total elements
while(t--)
{
scanf("%d",&n); // enter no. one at a time
a[0]=1; //initializes array with only 1 digit, the digit 1.
m=1; // initializes digit counter
temp = 0; //Initializes carry variable to 0.
for(i=1;i<=n;i++)
{
for(j=0;j<m;j++)
{
x = a[j]*i+temp; //x contains the digit by digit product
a[j]=x%10; //Contains the digit to store at position j
temp = x/10; //Contains the carry value that will be stored on later indeces
}
while(temp>0) //while loop that will store the carry value on array.
{
a[m]=temp%10;
temp = temp/10;
m++; // increments digit counter
}
}
for(i=m-1;i>=0;i--)
printf("%d",a[i]);
printf("\n");
}
return 0;
}

What is the largest prime factor of the number 600851475143?

I want to know that what is the error in my code.
int main () {
long long int number, large_factor=0, i=2;
printf ("Enter a number : ");
scanf ("%ld", &number);
while (number!=1) {
if (number%i==0) {
while (number%i==0) {
printf ("%ld\t", i);
number/=i;
}
large_factor=i;
}
i++;
}
printf ("\n\nThe largest prime factor is : %ld\n\n", large_factor);
return 0;
}
This code is running fine for smaller numbers but why it is failing for the large numbers?
Your format specifier everywhere is for long int you should use "%lld".
When I fix the format specifiers it runs fine for 600851475143 giving the largest prime factor 6857.
There must be something else going on. Assuming your compiler is compliant long long int should (at minimum) be a 64-bit integer and easily large enough to accommodate that value.
Try
printf("long long int max : %lld\n",LLONG_MAX);
Having added #include <limits.h> at the top.
It should produce a value no less than 9223372036854775807 and probably that exact number.
Here:
#include <limits.h>
#include <stdio.h>
int main () {
printf("long long int max : %lld\n",LLONG_MAX);
long long int large_factor=0, i=2;
long long int number=600851475143;
while (number!=1) {
if (number%i==0) {
while (number%i==0) {
printf ("%lld\t", i);
number/=i;
}
large_factor=i;
}
i++;
}
printf ("\n\nThe largest prime factor is : %lld\n\n", large_factor);
return 0;
}

Int array to store large numbers (over 20 digits)

I have an assignment that requires me to first set up integer arrays to store arbitrarily large numbers. By using each element of an int array, I can hold one digit per element because int variable types are 32 bits and can only reach up to about 2 billion before failing. I know that there are other libraries using BigInt but I wanted to make my own arrays instead.
I tested my code out, but it doesn't seem to be accepting values past 9 digits until it starts to fail.
int * toArray(int, int);
int main()
{
int n, *res, counter, i;
printf("Input: ");
scanf("%d", &n);
while(n>0){
n/=10;
counter++;
}
res = toArray(n, counter);
for(i=1;i<=counter;i++){
printf("%d", *(res)+i);
}
printf("\n");
}
int * toArray(int n, int counter)
{
int i;
int *numberArray = malloc(sizeof(int) * counter);
for(i=0; i< counter; i++)
{
numberArray[i] = n % 10;
}
return numberArray;
}
I want to be able to accept close to twenty digits at the very least. I know this can be done with int arrays, although char arrays (or strings) are also a possibility. But I wanted to use int arrays instead. Any help in understanding why it fails around 9 digits and suggestions for going past that would be very much appreciated. Thank you.
The problem is that you are reading an int from keyboard
scanf("%d", &n);
so therefore no matter how many digits you enter, you still will only get 9 digits.
In order to be able to enter an arbitrary number you would have to read it as a string instead, then convert it to your int array.
EDIT:
this way (for instance) would allow for 20 digits
char ch;
int digits[20];
int i = 0;
do
{
ch = fgetc(stdin);
if ( isdigit(ch) )
{
digits[i++] = ch - 48; // convert ASCII to int
}
}
while (isdigit(ch) && i < sizeof(digits)/sizeof(digits[0]));
#include<stdio.h>
#include<stdlib.h>
int *toArray(long long int n, int counter); int main() {
long long int n=0,copy_of_n=0;
int counter=0, i=0;
int *res=NULL;
printf("Input: ");
scanf("%lld", &n);//Refer note in the answer
copy_of_n=n;//see the while loop why use this.
while(n>0){
n/=10;//Good, but you are not storing it. copy_of_n does that.
counter++;//You didn't initialize this
}
res=toArray(copy_of_n, counter);
for(i=counter-1;i>=0;i--){//This ensures you get the numbers in a proper order and since index starts from 0 in the toArray function
printf("%d", res[i]);
}
printf("\n");
free(res);//You forgot this
return 0; }
int *toArray(long long int n, int counter) {
int i=0;
int *numberArray = malloc(sizeof(int) * counter);
memset(numberArray,0x00,counter*sizeof(int));//Good to do this
//Check for memory allocation
for(i=0; i< counter; i++)
{
numberArray[i] = n % 10;
n=n/10LL;//You have to remove the digits too
}
return numberArray; }
NOTE: Read in a while loop the integers in small parts because long long has limits of how many digits it can store. Another approach would be to store in a string and send split the string into exactly the max. no. of digits that can be stored in long long in the n variable and send it to the function, part by part.
long long size is implementation dependent, hence ensure you check the max. no. of digits it can accomodate.(It will ofcourse bypass your 9-digit limit as asked in question)

Resources