I’m writing my first ever program in C and it’s giving me a lot of problems.
It’s fairly simple; input a number and the output will be the corresponding term in the Fibonacci sequence where the first and second terms are 1. It was initially working as long as I didn’t put anything other than a number as the input; letters or special characters caused a segmentation fault. To fix this, I tried to reject all non-numeric inputs, and since I couldn’t find a function to do this I made my own. Unfortunately, it now gives a segmentation fault when a numeric input is given, and all non-numeric inputs are read as 26.
The compiler, gcc with pedantic warnings, only complains about my comments.
I’ve used GDB to narrow the segmentation fault to:
return strtol(c, n, 10);
Any help for identifying the problem and avoiding it next time would be greatly appreciated.
The Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
calcTerm(); //Run calcTerm()
return 0; //Return value & exit
}
int fibTerm(int term)
{
//Declare Variables
int a = 0;
int b = 1;
int next;
int x;
//Calculate the sequence
for (x = 0; x <= (term - 2); x++)
{
next = a + b;
a = b;
b = next;
}
return next; //return the requested output
}
int calcTerm()
{
//declare variables
int in;
char rawIn[256];
char **n;
int out;
printf("Input the term you want to find:\n"); //request input
//get input
fgets(rawIn, 3, stdin);
//define variables
in = isNumeric(rawIn); /*strtol(rawIn, n, 10) works*/
out = fibTerm(in);
//print result
printf("Term %i " "is %i", in, out);
}
int isNumeric(char test[256])
{
//declare variables
char validChars[10] = "0123456789"; //valid input characters
char *c = test;
char **n;
if (strpbrk(test, validChars)) //if input contains only valid characters ?
{
return strtol(c, n, 10); //return the input as an integer
//segmentation fault; strtol_l.c: no such file
}
else
{
printf("Please only input numbers."); //error message
}
}
nis unitialized and it points to nowhere.strtolwill try to write to the memory address pointed to byn, which could be anywhere in the memory and it is likely not pointing to an area where you are alloweed to write. Simply pass a null value there (i.e.strtol(c, 0, 10)).By the way, I’d try to use
sscanfto parse the number;sscanfreturns the number of tokens parsed successfully, so if you get a zero as a return value, the number was invalid. E.g.:And since you are reading from the standard input anyway, you can skip storing the line in a string and then calling
sscanf, you can simply usescanfto parse the standard input directly.