Ошибка сегментации для числового ввода - PullRequest
2 голосов
/ 01 июня 2011

Я пишу свою первую программу на C, и она доставляет мне много проблем.Это довольно просто;введите число, и результат будет соответствующим термином в последовательности Фибоначчи, где первый и второй термины равны 1. Первоначально он работал, пока я не поместил ничего, кроме числа, в качестве ввода;буквы или специальные символы вызвали ошибку сегментации.Чтобы исправить это, я попытался отклонить все нечисловые вводы, и так как я не мог найти функцию, чтобы сделать это, я сделал свой собственный.К сожалению, теперь он дает ошибку сегментации, когда задан числовой ввод, и все нечисловые входы читаются как 26.

Компилятор, gcc с педантичными предупреждениями, жалуется только на мои комментарии.Я использовал GDB для сужения ошибки сегментации до:

return strtol(c, n, 10);

Любая помощь для выявления проблемы и ее избежания в следующий раз будет принята с благодарностью.

Код:

#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
  }

}

Ответы [ 2 ]

4 голосов
/ 01 июня 2011

n унифицирован и указывает на никуда.strtol попытается выполнить запись по адресу памяти, указанному n, который может находиться в любом месте памяти и, вероятно, не указывает на область, в которой вам разрешено писать.Просто передайте туда нулевое значение (т.е. strtol(c, 0, 10)).

Кстати, я бы попытался использовать sscanf для разбора числа;sscanf возвращает количество проанализированных токенов, поэтому, если вы получите ноль в качестве возвращаемого значения, число будет недействительным.Например:

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

И так как вы все равно читаете со стандартного ввода, вы можете пропустить сохранение строки в строке и затем вызвать sscanf, вы можете просто использовать scanf для анализа стандартного вводанепосредственно.

1 голос
/ 01 июня 2011

Вы получаете случайный вывод для входа 1, потому что в fibTerm цикл никогда не будет введен (for (x = 0; x <= (term - 2); x++) с term == 1).Следовательно, неинициализированное значение next будет возвращено

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...