【问题标题】:Segmentation Fault for numeric input数字输入的分段错误
【发布时间】:2011-06-01 10:16:14
【问题描述】:

我正在用 C 编写我的第一个程序,它给我带来了很多问题。 这相当简单;输入一个数字,输出将是斐波那契数列中的相应项,其中第一项和第二项为 1。只要我没有将除数字以外的任何东西作为输入,它最初就可以工作;字母或特殊字符导致分段错误。为了解决这个问题,我尝试拒绝所有非数字输入,并且由于我找不到执行此操作的函数,所以我自己制作了。不幸的是,它现在在给出数字输入时会出现分段错误,并且所有非数字输入都被读取为 26。

带有迂腐警告的编译器 gcc 只抱怨我的 cmets。 我使用 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
  }

}

【问题讨论】:

  • 该程序对我来说运行正确
  • 更新后的代码对我来说很好;这里和那里有一些奇怪的地方(例如在isNumeric 中使用sscanf,它基本上用c 中找到的字符串的第一个单词覆盖validChars),但总的来说还可以。请注意,您当前的代码从 (0, 1) 开始计算斐波那契数列,而不是从 (1, 1) 开始。
  • 我会尽力解决这个问题...感谢您的帮助。

标签: c segmentation-fault strtol


【解决方案1】:

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 的输入会生成看似随机的结果。 1 的输出:“第 1 项是 1197354752”。
  • ...或者问另一个问题,只发布出现问题的代码部分。
  • 我认为这是计算的一部分...输入 1 导致 x 从 0 开始并增加直到达到 -1。我应该早点看到的。
  • 啊,你说得对。只需确保 next 没有未初始化,它应该可以工作。
【解决方案2】:

您会得到输入 1 的随机输出,因为在 fibTerm 中永远不会进入循环(for (x = 0; x &lt;= (term - 2); x++)term == 1)。所以会返回未初始化的next

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 2018-09-06
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    相关资源
    最近更新 更多