Segmentation Fault for numeric input
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
i开发者_运维百科nt 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
}
}
n
is unitialized and it points to nowhere. strtol
will try to write to the memory address pointed to by n
, 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 sscanf
to parse the number; sscanf
returns the number of tokens parsed successfully, so if you get a zero as a return value, the number was invalid. E.g.:
const char* my_string = " 123";
const char* my_invalid_string = "spam spam spam";
int number;
sscanf(my_string, "%d", &number); // this should return 1
sscanf(my_invalid_string, "%d", &number); // this should return 0
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 use scanf
to parse the standard input directly.
You get random output for the input 1
because in fibTerm
the loop will never be entered (for (x = 0; x <= (term - 2); x++)
with term == 1
). Therefore, the uninitialized next
value will be returned
精彩评论