C Segmentation Fault With Printf() and Scanf() - c

I'm new to C, and I'm getting a segmentation fault that I can't understand. I have the following program, which attempts to calculates the number of factors of a strictly positive number:
#include <stdio.h>
#include <math.h>
int numberOfFactors (int number, int factor) {
if (number % factor == 0) {
number = number/factor;
return numberOfFactors(number, factor) + 1;
} else {
return 0;
}
}
int check (int x) {
if (x>0) {
return 1;
} else {
return 0;
}
}
int main(void) {
int number;
printf("Please enter a positive integer n such that n >= 1: ");
scanf("%d", &number);
if (check(number)){
int i;
for (i=1; i<=number; i++) {
int factors;
factors = numberOfFactors(number, i);
printf("%d^%d ", i, factors);
}
}
return 0;
}
The segmentation fault occurs immediately after entering an integer and ENTER after these lines in main():
printf("Please enter a positive integer n such that n >= 1: ");
scanf("%d", &number);
What in these lines is causing the segmentation fault, and what can I do to avoid it?

Your recursion doesn't stop if you try to divide out factor one.
Just let factor never be 1:
for (i=2; i<=number; i++) {
int factors;
factors = numberOfFactors(number, i);
printf("%d^%d ", i, factors);
}
I should say WHY it segfaults: It's because every function call pushes the current program counter (the position in your program where you currently stand) and function arguments on the stack (aka call stack), where the stack is a relatively small memory block used for, well, function calling and local variables.
So if you are pushing your stack too hard, it will fall over. End of game, aka segfault ;)

You probably have a problem with this recursion:
int numberOfFactors (int number, int factor) {
if (number % factor == 0) {
number = number/factor;
return numberOfFactors(number, factor) + 1;
} else {
return 0;
}
}
Change your numberOfFactors to something like:
int numberOfFactors (int number)
{
int i=1;
int ret=0;
for(;i<=number;i++) {
if (number%i == 0) {
ret++;
}
}
return ret;
}
And then, change this portion:
if (check(number)){
int i;
for (i=1; i<=number; i++) {
int factors;
factors = numberOfFactors(number, i);
printf("%d^%d ", i, factors);
}
}
To something simpler like:
if (check(number)){
factors = numberOfFactors(number);
printf("%d^%d ", number, factors);
}

Related

Function to find odd numbers returns extra value - C Language

I wrote a code in C to find the odd numbers from a given interval of min and max number. The function works well when it is inside the int main() but not well when outside the program as a function.
What's more is that it also prints the incremented number outside the max number given.
This is the code...
#include <stdio.h>
// My Function
int odd_numbers(int x, int y) {
for (int i = x; i <= y; ++i) {
if (i % 2 == 1) {
printf("%d\n",i);
}
}
}
// Main Program
int main(void) {
int min_num, max_num;
printf("Input your minimum number: ");
scanf("%d", &min_num);
printf("Input your maximum number: ");
scanf("%d", &max_num);
printf("%d",odd_numbers(min_num,max_num));
}
and this is the output...
As you can see, it adds an 11 besides the 9...
How can I solve this? I've tried return 0; and it returns the value 0 but i only want to return no number except the odd numbers.
Here is the working code.
Notes
Change the return type of odd_numbers from int to void because you are not returning anything when the function is called.
Only call the function odd_numbers, no need to printf anything because odd_numbers already does the job.
#include <stdio.h>
// My Function
void odd_numbers(int x, int y) {
for (int i = x; i <= y; i++) {
if (i % 2 != 0) {
printf("\n%d",i);
}
}
}
// Main Program
int main(void) {
int min_num, max_num;
printf("Input your minimum number: ");
scanf("%d", &min_num);
printf("Input your maximum number: ");
scanf("%d", &max_num);
odd_numbers(min_num,max_num);
}
Here is the modified code.
you have declare function return type int but return nothing. odd_numbers made to void type. no need to return anything
code:
#include <stdio.h>
// My Function
void odd_numbers(int x, int y)
{
int i = 0;
for (int i = x; i <= y; i++)
{
if (i % 2 != 0)
{
printf("%d\n", i);
}
}
}
// Main Program
int main(void) {
int min_num, max_num;
printf("Input your minimum number: ");
scanf("%d", &min_num);
printf("Input your maximum number: ");
scanf("%d", &max_num);
odd_numbers(min_num, max_num);
return 0;
}

Pass by reference method

The question is to find twin prime numbers using pass by reference. I tried to code it out but it doesn't work the way normal pointers would? (Cannot use malloc function)
#include <stdio.h>
int twinp(int *n)
{
int i=2;
for (i=2; i<= *n/2; i++)
{
if (*n%i == 0)
return 0;
}
if (i > *n/2)
return 1;
}
int main ()
{
int i, c= 0;
printf("Twin prime numbers before 100 are: ");
for (i = 2; i <= 100; i++)
{
if (twinp(&i) && twinp(&i+2))
{
printf ("(%d, %d) ", i, i+2);
c++;
}
}
printf (" \nTotal number of twin prime pairs: %d", c); return 0;
}
If you want to pass the reference to a function in c, you have to use pointers.
Use the '&' keyword to reference the address of the value. Remember to have a memory location at moment to pass the reference, so you have to store the 'i+2' in local function and pass the reference to your function. Then use '*' to access the value.
#include <stdio.h>
int twinp(int * n)
{
int i=2;
for (i=2; i<= *n/2; i++)
{
if (*n%i == 0)
return 0;
}
if (i > *n / 2)
return 1;
}
int main ()
{
int i, c= 0;
printf("Twin prime numbers before 100 are: ");
for (i = 2; i <= 100; i++)
{
int i_plus_2 = i+2;
if (twinp(&i) && twinp(&i_plus_2))
{
printf ("(%d, %d) ", i, i+2);
c++;
}
}
printf (" \nTotal number of twin prime pairs: %d\n", c); return 0;
}
You are on the right track. When you pass by reference, you pass a memory location & of a variable in the calling function (twinp(..)) and in the actual function implementation, you'd catch that memory location via * pointer. When you actually try to use the value, you have to make sure you deference with the *.
Another approach you can take would be the below:
In the function itself, we do our checks for that current number AND the +2 number.
Your loop in your main function will take care of all the iterations up to 100.
If we find the number is prime, we print in the function. If not, we return and continue to the next iteration in our main loop.
#include <stdio.h>
void twinp(int *n)
{
for(int i= 2; i < *n; i++) {
if((*(n) % i) == 0 || (*(n) + 2) % i == 0)
return;
}
printf("(%d, %d),", *n,*n +2);
}
int main ()
{
int i, c = 0;
printf("Twin prime numbers before 100 are: ");
for (i = 3; i < 100; i++)
{
twinp(&i);
}
printf (" \nTotal number of twin prime pairs: %d", c);
return 0;
}

Do we have to create an even and an odd array?

How can we modify the following code (which initially asks the user for 10 numbers to be entered, get stored in an array, and printed on the screen) so that the even numbers are printed on the first line, and the odd on the second:
#include <stdlib.h>
#include <stdio.h>
int i,j;
int array_1[10];
int main() {
for(i=0;i<10;i++) {
printf("Enter a number: ");
scanf("%d", &array_1[i]);
}
printf("The elements of the array are: ");
for (j=0;j<10;j++) {
printf("%d ", array_1[j]);
}
printf("\n");
return 0;
}
O(n) Solution:
you have to add odd numbers at the back of the array and add the even numbers at the front of the array and keep track of the indexes.
int array_1[10];
int main() {
int even = 0, odd = 10;
for (int i = 0; i < 10; i++) {
printf("Enter a number: ");
int inp;
scanf("%d", &inp);
if (inp % 2 == 0) {
array_1[even++] = inp;
} else {
array_1[--odd] = inp;
}
}
// even numbers
for (int i = 0; i < even; i++) {
printf("%i ", array_1[i]);
}
printf("\n");
// odd numbers
for (int i = 9; i >= odd; i--) {
printf("%i ", array_1[i]);
}
printf("\n");
return 0;
}
Since you asked, here is how I would do it. I suspect this may leave you with more questions than answers through.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#define NUMBERS_SIZE 10
typedef bool (*number_validator)(int num);
bool isEven(int num)
{
return (num & 1) == 0;
}
bool isOdd(int num)
{
return (num & 1) != 0;
}
void print(const char *title, int *array, int array_size, number_validator isValid)
{
printf("%s", title);
bool first = true;
for (int i = 0; i < array_size; ++i)
{
if (isValid(array[i]))
{
if (!first)
{
printf(", ");
}
printf("%d", array[i]);
first = false;
}
}
printf("\n");
}
int main()
{
int numbers[NUMBERS_SIZE] = { 0 };
for (int i = 0; i < NUMBERS_SIZE; i++)
{
printf("Enter a number: ");
scanf("%d", &numbers[i]);
}
printf("\n");
print("Even: ", numbers, NUMBERS_SIZE, isEven);
print(" Odd: ", numbers, NUMBERS_SIZE, isOdd);
return 0;
}
Demo on ideone
you can try this way.I have used binary AND(&) instead of MOD(%) as it is faster:
#include <stdlib.h>
#include <stdio.h>
int i,j;
int array_1[10];
int main()
{
for(i=0; i<10; i++)
{
printf("Enter a number: ");
scanf("%d", &array_1[i]);
}
printf("The Even elements of the array are: ");
for (j=0; j<10; j++)
{
if((array_1[j]&1) == 0)
printf("%d ", array_1[j]);
}
printf("\nThe Odd elements of the array are: ");
for (j=0; j<10; j++)
{
if((array_1[j]&1) != 0)
printf("%d ", array_1[j]);
}
printf("\n");
return 0;
}
No need to create a new array. You can just go through it first checking for even numbers, and then again for odd numbers. Also, there's no need to declare i and j before using them. You can just declare them and initialize them in the for loop:
#include <stdlib.h>
#include <stdio.h>
int array_1[10];
int main() {
for(int i=0;i<10;i++) {
printf("Enter a number: ");
scanf("%d", &array_1[i]);
}
printf("The elements of the array are: ");
// Print even numbers
for (int j=0;j<10;j++) {
if(array_1[j] % 2 == 0)
printf("%d ", array_1[j]);
}
printf("\n");
// Print odd numbers
for (int j=0;j<10;j++) {
if(array_1[j] % 2 != 0)
printf("%d ", array_1[j]);
}
printf("\n");
return 0;
}
Edit: As tadman suggested in the comment below, there's a better and cleaner way to do this kind of task. As you can see in the above example, I'm repeating 4 lines of code where only one character changes. This task could be abstracted into a function to reduce code repetition:
void printIfMod(int* arr, size_t array_size, int mod){
for (int j=0;j<array_size;j++) {
if(arr[j] % 2 != mod)
continue;
printf("%d ", arr[j]);
}
printf("\n");
Remember to add a function prototype before main if you place the function after main:
void printIfMod(int* arr, size_t array_size, int mod);
int main(){...}
Now, to print the numbers, call the method with modulo 0 to get even numbers, and 1 to get odd numbers:
// Print even numbers
void printIfMod(&array_1, 10, 0);
// Print odd numbers
void printIfMod(&array_1, 10, 1);
One last note, hard-coding array_size is not wise, and that goes for all arrays. I recommend using sizeof() to dynamically calculate the size of your array:
size_t size = sizeof(array_1) / sizeof(int);
// Print even numbers
void printIfMod(&array_1, size, 0);
// Print odd numbers
void printIfMod(&array_1, size, 1);

A little problem with functions and arrays

I'm doing a program that check if 5 numbers that the user insert are even or odd, then they will be stored into an array and finally these values will be printed out on screen. In order to do this i've divided this program in two functions just to understand how the functions and the arrays works together, but it doesn't print the values that i've putted in. Why?
int check_even_and_odd(int number, int list[]){
printf("Insert the numbers\n");
scanf("%d", &list[number]);
if (number % 2 == 0) {
printf("Even\n");
}
else{
printf("Odd\n");
}
return 0;
}
int main () {
int k;
int i = 0;
int list2[5] = {0};
while (i < 5) {
i++;
k = check_even_and_odd(i, &list2[i]);
}
i = 0;
while (i < 5) {
i++;
printf("\n%d\n", list2[i]);
}
return 0;
}
Edit: Now that the main issue is gone, I want to add a little improvement to this little project. I want that the program tells to me how many Even or Odd number are in the array, but i don't know how to do it. I was thinking about adding 2 counters into the if statement (one for the even number and one for the odd numbers) but once i do this i don't know how to continue.
The program with the counters is this:
void check_even_and_odd(int number, int list[]){
int even = 0;
int odd = 0;
printf("Insert the numbers\n");
scanf("%d", &list[number]);
if (number % 2 == 0) {
even++;
}
else{
odd++;
}
printf("Even numbers are: %d\n", even);
printf("Odd numbers are: %d\n", odd);
}
int main () {
int i = 0;
int list2[5] = {0};
while (i < 5) {
i++;
check_even_and_odd(i, list2);
}
i = 0;
while (i < 5) {
i++;
printf("\n%d\n", list2[i]);
}
return 0;
}
Obviously it isn't complete, but as i have already said, i don't know how to continue
Your function expects an array argument but you are passing the address of individual elements of the array, so it won't work properly, you'll just need to use the correct argument:
k = check_even_and_odd(i, list2);
Quibble: k is never used so you don't really need it. You can just make your function void and remove the variable:
void check_even_and_odd(int number, int list[]){
printf("Insert the numbers\n");
scanf("%d", &list[number]);
if (number % 2 == 0){
printf("Even\n");
}
else{
printf("Odd\n");
}
}
int main(){
int i = 0;
int list2[5] = {0};
while (i < 5){
i++;
check_even_and_odd(i, list2);
}
i = 0;
while (i < 5){
i++;
printf("\n%d\n", list2[i]);
}
return 0;
}
Your fault is in line scanf("%d", &list[number]); just need to change it to scanf("%d", &list); but i think you are miss understanding whole array and pointer logic. You can't pass list as argument and if you do that, The compiler will changed it to pointer automatically. So if you want to tell a function about your list you just have to pass it your list address in memory (pointer). So you should do it like:
#include <stdio.h>
int How_Many_Odd = 0;
int How_Many_Even = 0;
void Add_To_List(int Number, int *ListIndex){
printf(
"Number %d is %s\n",
Number,
(Number % 2 == 0)? "Even": "Odd" // check if is odd or even
);
if(Number % 2 == 0)
How_Many_Even++;
else
How_Many_Odd++;
// changing value of pointer ListIndex to Number
*ListIndex = Number;
}
int main(){
// first creating integer array with size of 5
int List[5];
for(int i=0; i < 5; i++){
// waiting for user to enter number
int value;
scanf("%d", &value);
// changing value of index 0 to 3
Add_To_List(value, &List[i]);
}
// showing how many odds and how many evens
printf("%d numbers are even and %d numbers are odd\n", How_Many_Even, How_Many_Odd);
// you can show every index value too
for(int i=0; i < 5; i++)
printf("value of index %d is %d\n", i, List[i]);
return 0;
}
I recommend you to learn about pointer that will fix your issues
Here is your code fixed:
#include <stdio.h>
void check_even_and_odd(int number, int list[], unsigned int *even_count)
{
printf("Insert the numbers\n");
scanf("%d", &list[number]);
if (number % 2 == 0) {
printf("Even\n");
*even_count += 1;
}
else
{
printf("Odd\n");
}
}
int main()
{
unsigned int even_count;
int i = 0;
int list2[5] = {0};
while (i < 5)
{
check_even_and_odd(i, list2, &even_count);
i++;
}
i = 0;
while (i < 5)
{
printf("\n%d\n", list2[i]);
i++;
}
printf("There are %d even numbers and %d odd ones.\n", even_count, 5 - even_count);
return 0;
}
Basically, your main problem is in passing the list to the function in k = check_even_and_odd(i, &list2[i]);, as you should be passing the entire list, not a specific number in the list.
regarding:
if (number % 2 == 0) {
This is checking the passed in parameter rather than the value entered by the user. Suggest:
...
if( (list[number] % 2) == 0 )
{
printf( "%s\n", "number is even" );
....

C recursive program to print all prime factors of a given number from the biggest factor to the smallest

i'm trying to write a program that print the prime factors of a given number ,but i need to print them from the biggest factor to the smallest, for example:
for the input 180 the output will be: 5*3*3*2*2,
any suggestions? here is what i got for now :
#include<stdio.h>
void print_fact(int n)
{
if (n==1)
return;
int num=2;
while (n%num != 0)
num++;
printf("*%d",num);
print_fact (n/num);
}
int main ()
{
int n;
printf("please insert a number \n");
scanf("%d",&n);
print_fact(n);
}
for this code the output is :
*2*2*3*3*5
You can simply print the output after the recursive call returns. You need to slightly modify how you display the *, which I leave to you.
#include<stdio.h>
void print_fact(int n)
{
if (n==1)
return;
int num=2;
while (n%num != 0)
num++;
// printf("*%d",num); // remove from here
print_fact (n/num);
printf("%d ",num); // put here
}
int main ()
{
int n;
printf("please insert a number \n");
scanf("%d",&n);
print_fact(n);
}
The output this gives on input 180 is:
5 3 3 2 2
Aside, there are much more efficient ways of actually finding the numbers though.
It is much faster to find them in the ascending order, mathematically speaking. Much, much faster.
The solution, if you don't want to bother yourself with dynamic arrays, is recursion. Find the lowest prime factor, recurse on the divided out number (num /= fac), and then print the earlier found factor, which will thus appear last.
to change the order in which they are printed, you could put the printf statement after the print_fact statement. To get rid of thew leading *, you would probably want to store the results and display them after computation
well, i'm trying to optimize my algorithm
this is my code for now:
functions code
#include "prime_func.h"
int divisors(int x) /* Function To set the maximum size of the future array,
Since there is no way to find the number of primary factors
without decomposing it into factors,
we will take the number of total number divisors
(which can not be greater than the number of primary factors) */
{
int limit = x;
int numberOfDivisors = 0;
if (x == 1) return 1;
for (int i = 1; i < limit; ++i) {
if (x % i == 0) {
limit = x / i;
if (limit != i) {
numberOfDivisors++;
}
numberOfDivisors++;
}
}
return numberOfDivisors;
}
void find_fact(int n, int *arr, int size, int i) //func to find the factors and apply them in allocated array
{
int num = 2;
if (n < 2)
{
printf("error\n");
return;
}
while (n%num != 0)
num++;
arr[i++] = num;
find_fact(n / num, arr, size, i);
}
void print_fact(int *arr, int size) // func to print the array in reverse
{
int i = 0;
int first;
first = FirstNumToPrint(arr, size);
for (i = first; i>0; i--)
printf("%d*", arr[i]);
printf("%d", arr[0]);
}
int FirstNumToPrint(int *arr, int size) // func to find the first number to print (largest prime factor)
{
int i;
for (i = 0; i < size; i++)
if (arr[i] == 0)
return i - 1;
}
int first_prime(int num) // for now i'm not using this func
{
for (int i = 2; i<sqrt(num); i++)
{
if (num%i == 0)
{
if (isprime(i));
return(i);
}
}
}
bool isprime(int prime) // for now i'm not using this func
{
for (int i = 2; i<sqrt(prime); i++)
{
if (prime%i == 0)
return(false);
}
return(true);
}
main code
#include "prime_func.h"
int main()
{
int n,i=0; // first var for input, seconde for index
int *arr; // array for saving the factors
int size;//size of the array
printf("please insert a number \n");// asking the user for input
scanf("%d", &n);
size = divisors(n); //set the max size
arr = (int *)calloc(size,sizeof(int)); //allocate the array
if (arr == NULL) // if the allocation failed
{
printf("error\n");
return 0;
}
find_fact(n, arr,size,i);// call the func
print_fact(arr,size); //print the result
free(arr); // free memo
}
#WillNess #GoodDeeds #mcslane

Resources