开发者

Segmentation Fault for numeric input

开发者 https://www.devze.com 2023-03-09 22:12 出处:网络
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 fir

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

0

精彩评论

暂无评论...
验证码 换一张
取 消