0

私は独学で Pro*C を学んでいます。これは、データベース内のレコードを介してカーソルを移動するプログラムであり、コンパイルして実行します。「Guest_IDを入力してください(終了するにはexitを入力してください)>>」というプロンプトまで表示されます。その後、整数を入力すると「Segmentation fault (core dumped)」としてエラーになります。文字列を入れると外側の for ループのすぐ内側で条件分岐に入るようです。

if(nGuest_ID==0)
{
      printf("BYE\n");
      exit(0);
}

「BYE」を出力して終了します。変数がどのように宣言され、SQL から入力されるかについてはまだ慣れていないため、ここでのトラブルシューティングにどの宣言が重要になるかはわかりませんでした。そのため、ここではコードをほとんどそのままにしておきます。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
exec sql include sqlca;

// OK - Here we GO
void main()
{
    // First, create all the variables that we will need to communicate between 
    // the "C" program and the database
    exec sql begin declare section;
        //VARCHAR sLastName[51], sFirstName[51], sHotelName[51], sCheckInDate[12], sRoom[11];
        VARCHAR sLastName[51], sFirstName[51], sHotelName[51], sTransDate[11];
        //int nDays, nGuest_ID, nCount;
        int nGuest_ID, nQuantity, nUnitPrice, nCount, nHotelID, nItemID;
        //VARCHAR sInCity[11];
        VARCHAR sItemName[31], sTaxable[11];
        VARCHAR sUserID[21], sPassword[21];
    exec sql end declare section;
/////// begin needs work ///////
        // Now define the cursor we will use to get all of the charges that the guest incurred at all hotels
    exec sql declare dbGuest cursor for
        Select G.Guest_ID, G.Last_Name, G.First_Name, C.Item_ID, C.Item_Name, C.Quantity, C.Unit_Price, C.Trans_Date, H.Hotel_Name, H.Hotel_ID, SI.Taxable
        From Hotel H, Charge C, Stay S, Guest G, Sales_Item SI Where
        C.Stay_ID=S.Stay_ID And H.Hotel_ID=S.Hotel_ID And G.Guest_ID=S.Guest_ID
            And SI.Item_ID=C.Item_ID
        Group By S.Guest_ID;
//////// end needs work ///////
    // Set up the user-id and password to access my database
    // Because we are using the local database on this server
    // we don't need to use any database location or SID
    strcpy(sUserID.arr,"myusername"); 
    strcpy(sPassword.arr,"mypassword"); 
    sUserID.len=strlen(sUserID.arr);
    sPassword.len=strlen(sPassword.arr);
    exec sql connect :sUserID identified by :sPassword;

    // sqlca.sqlcode is a variable that is set based on the last command sent in to the database
    // a value anything other than zero for what we just did (connect to the database) indicates
    // a error.
    if(sqlca.sqlcode !=0)
       {
        //printf("Sorry, cannot connect to server, pgm aborted %s\n",sqlca.sqlcode); //correction 2/5/14
        printf("Sorry, cannot connect to server, pgm aborted %d\n",sqlca.sqlcode); //change to %d
        exit(1);
       }
    //we made it here, so we were able to open the database correctly
    exec sql SELECT COUNT(*) INTO :nCount FROM Guest;
    printf ("There are %d Guests.\n",nCount);
    for(;;){
        // Read in through stdio the Guest we want to query, then set it up do we can use it
        printf("Enter a Guest_ID(type exit to terminate)>>\n");
        scanf("%d",nGuest_ID);
        //Guest_ID.len= strlen(Guest_ID.arr);
        if(nGuest_ID==0)
        {
            printf("BYE\n");
            exit(0);
        }
        printf("%s %s %s %s %d\n","Charge Summary for:", sFirstName.arr, sLastName.arr, " Guest_ID:", nGuest_ID);
        //printf("I do not work yet (type exit to terminate)>>\n");
                // Open our cursor and begin reading records
        exec sql open dbGuest;
        for(;;)
        {
            //exec sql fetch dbGuest into :nGuest_ID, :sLastName, :sFirstName, :sHotelName, :sCheckInDate, :nDays, :sRoom;
            exec sql fetch dbGuest into :nGuest_ID, :sLastName, :sFirstName, :nItemID, :sItemName, :nQuantity, :nUnitPrice, :sTransDate, :sHotelName, :nHotelID;
            if(sqlca.sqlcode !=0)  // If anything went wrong or we read past eof, stop the loop
            {
                break;
            }
            // Do the crazy stuff to end the C-Strings
            sLastName.arr[sLastName.len] = 0;
            sFirstName.arr[sFirstName.len] = 0;
            sItemName.arr[sItemName.len] = 0;
            sTransDate.arr[sTransDate.len] = 0;
            sHotelName.arr[sHotelName.len] = 0;

            // Print out the information for this guest
            printf("%s %d %s %s \n", "Sales_Item: ", nItemID, " - ", sItemName.arr);
        }
        // close the cursor and end the program
        exec sql close dbGuest ;
    }
    exit(0);
}

単純な間違いを犯していると確信していますが、検索で役立つものは何も見つかりませんでした。私はこれをサーバーで実行していますが、デバッグが返されません (これは、これまでに解決できなかった唯一の主要なバグです)。通常、C プログラムはデバッガーで実行されますが、これは Pro C であり、Oracle Pro C のデバッグ全体に戸惑っています (リモート データベースで実行されているため)。この種のエラーでは、通常、メモリが適切に割り当てられていないのではないかと疑っていますが、ここではそのようなものは見当たりません。

これらを試しましたが、役に立ちませんでした:

C でのセグメンテーション違反 (コア ダンプ) ランタイム エラー

あまり役に立たないエラー -- 宿題のセグメンテーション エラー (コア ダンプ)

セグメンテーション違反 (コアダンプ)

stdin から読み取ったセグメンテーション違反 (コア ダンプ)

4

1 に答える 1