0

私はプログラミングにまったく慣れていません。球と円柱の体積と表面積を見つけるために独自のプログラムを作成しようとしています。このプログラムが残りのコードに到達する前にクラッシュし続ける理由がわかりません。間違っているかもしれないと思いchar*ますが、なぜそうなるのかわかりません。

int main()
{
    char* solid;
    char* unit;
    printf("Welcome to the Center of Spheres and Cylinders!\n");
    printf("Would you like to look at a Sphere or a Cylinder?: ");
    scanf("%s", solid);
        if(solid == "Cylinder" || solid == "cylinder")
        {
            printf("You chose to look at a Cylinder.\n");

        else if(solid == "Sphere" || solid == "sphere")
        {
            printf("You chose to look at a Sphere.\n");

入力した直後にscanf.クラッシュします。円柱または球のいずれかを入力するとクラッシュします。お手伝いありがとう

4

4 に答える 4

3

solidは文字ポインタであり、でデータを読み込もうとしたときにプログラムがクラッシュする原因となる割り当てられたメモリ位置を指していません(そのため、観察すると、その呼び出しの直後にクラッシュします)。scanf()

宣言した後

 char *solid;

malloc()それが指すために、ある程度のストレージが必要です。または、という名前の配列を宣言することもできますsolid

 char solid[100];

クラッシュは、用事ポインタに問題があることを示すのに役立つという点で、実際には良いことであることに注意してください。残念ながら、メモリ内のポインタが指している場所によっては、これが常に発生するとは限りません。

于 2012-09-03T03:20:58.857 に答える
0

他の人が指摘しているように、あなたのプログラムにはいくつかの「欠陥」があります。

  1. 「星」はポインタを示します。ポインタはメモリ内の場所を指している必要があります。これは、malloc()、ポインタの割り当て/操作、または明示的なビットアドレスを介して実行できます。ポインターの詳細については、次を参照してください。http: //pw1.netcom.com/~tjensen/ptr/pointers.htm(しかし、真剣に、ポインター?あなたはプログラミングの初心者だと言っています。ポインターはCだけでなく、コンピュータサイエンスでも高度な概念です。とにかく、現時点ではそれらについてあまり考えないでください。)

  2. Cでの文字列比較は、単純な等式演算子ではなく、ビット比較(ラ​​イブラリによって自動的に実行されます)によって実行されます。等式演算子(==)は、プリミティブ型(int、charなど)のみを比較し、ユーザー定義型または配列(文字列は文字配列)は比較しません。strcmp()(またはstrncmp()を使用して、オプションのオフセットから最初のnバイトを比較する)を使用する必要があります。詳細については、Googleでstrcmp()およびstrncmp()のドキュメントを検索できます。

これらの概念を念頭に置いて、プログラムは次のようになります。

#include <string.h> /**Contains string manipulation functions; very important **/
#include <ctype.h> /**Contains tolower() **/
int main()
{
    char* solid;
    char* unit;

    printf("Welcome to the Center of Spheres and Cylinders!\n");
    printf("Would you like to look at a Sphere or a Cylinder?: ");
    scanf("%s", solid);

    if(strcmp(tolower(solid), 'cylinder') == 0)
    {
        printf("You chose to look at a Cylinder.\n");

    else if(strcmp(tolower(solid), 'sphere') == 0)
    {
        printf("You chose to look at a Sphere.\n");

    }
    /** Other code here **/
    return 0;
}

ご想像のとおり、tolower()は文字列を小文字に変換します。また、追加の参考までに、配列はポインターであるため、scanfからの入力を格納するために「スター」表記を使用することの正当性。

于 2012-09-03T03:54:28.483 に答える
0

問題は回線にあります

if(solid == "Cylinder" || solid == "cylinder")

UはCのような文字列を比較できません。代わりに、Cで使用可能なstrcmpライブラリ関数を使用してください。

コードは次のようになります

if( (strcmp(solid,"Cylinder")==0) || (strcmp(solid,"cylinder")==0) )

お役に立てれば。

于 2012-09-03T03:24:25.807 に答える
0

char* solid;任意の場所を指す文字ポインターを作成します(少なくとも、コードにある自動変数の場合)。次に、その場所にアクセスしようとするとsccanf、有効なバッキングストレージがないため、未定義の動作が呼び出されます。

のようなものは、格納される文字のためのスペースを割り当てるので、その差し迫った問題を解決するバッキングストレージchar solid[100]; を作成します。ただし、コードには他に少なくとも2つの問題があります。


1つ目は、Cの文字列をと比較しないことです。これは、ポインタの背後==にあるコンテンツではなく、単にポインタを比較するだけです。コンテンツを比較するために、Cは次ではなく関数soを提供します。strcmp

if (solid == "something")

あなたが持っている必要があります:

if (strcmp (solid, "something") == 0)

一部の実装では、大文字と小文字を区別しないものが提供さstricmpれる場合があるため、次のことを行う必要はありません。

if ((strcmp (solid, "something") == 0) || (strcmp (solid, "Something") == 0))

代わりに:

if (stricmp (solid, "something") == 0)

これにより、。などの任意の文字を大文字または小文字にすることができますSomeThing

ただし、これは標準のCではないため、どこでも利用できるとは限りません。


あなたの他の主要な問題はにありますscanf("%s")。ここで無制限の文字列を使用することは、ユーザーが予想以上に入力するとバッファオーバーフローが発生する可能性があるため、安全ではありません。たとえば、前述の文字を使用char solid[100]し、ユーザーが500文字を入力すると、スタックが破棄され、さらに別のクラッシュが発生する可能性があります。

本当に堅牢なユーザー入力関数が必要な場合は、これを見てください。オーバーフロー保護があり、後続の入力が影響を受けないように、必要に応じて残りの行を破棄します。

于 2012-09-03T03:39:41.697 に答える