2

初めて C でプログラムを書いていますが、多くの問題が発生しています。かなり単純です。数値を入力すると、最初と 2 番目の項が 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
  }

}
4

2 に答える 2

4

nはユニット化されており、どこも指していません。strtolが指すメモリアドレスに書き込もうとしますn。これはメモリ内のどこにでもある可能性があり、書き込みが許可されている領域を指していない可能性があります。そこにnull値を渡すだけです(つまり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

于 2011-06-01T10:23:38.977 に答える
1

ループには入力されない1ため、入力に対してランダムな出力が得られます( with )。したがって、初期化されていない値が返されますfibTermfor (x = 0; x <= (term - 2); x++)term == 1next

于 2011-06-01T11:25:00.083 に答える