2014-02-19 17 views
0

我在教自己Pro * C,這是一個程序,帶有遊標通過數據庫中的記錄,並編譯並運行。它得到的只是提示「輸入Guest_ID(輸入exit來終止)>>」。之後,如果輸入整數,則會出現「分段錯誤(核心轉儲)」錯誤。如果輸入一個字符串,它似乎立即進入外部for循環內的條件,在Oracle Pro * C - 分段錯誤(核心轉儲)

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調試(因爲它運行在遠程數據庫上)而感到迷惑。有了這種錯誤,我通常會懷疑沒有正確地分配內存,但我在這裏沒有看到類似的東西。

通過這些,但沒有幫助跑到:

Segmentation fault (core dumped) runtime error in C

Not so Useful Error -- Segmentation Fault (Core Dump) in Homework Assignment

Segmentation Fault(core dumped)

Segmentation fault (core dumped) read from stdin

+0

'dbx core '可以顯示最後一行執行! –

+0

該服務器上未啓用dbx – stackuser

回答

4

由於nGuest_ID是int,調用scanf()的時候,你需要p的nGuest_ID rovide地址:

scanf("%d",&nGuest_ID); 

這是核心的可能原因轉儲您遇到,但是,也OracleUser提出了一些很好的建議。

希望有所幫助。

+0

是的,謝謝+1,它允許代碼繼續。但我想知道爲什麼它會像這樣運行 - 「Charge Summary for:}▒Guest_ID:1」,因爲它應該打印最後一個名字。這可能是我初始化變量的順序問題,還是我遇到了一個完全不同的問題? – stackuser

+0

似乎sFirstName和sLastName是聲明的,但未嘗試打印它們之前未初始化或填充任何位置。所以,你只是從內存中打印隨機垃圾。 –

+0

@ MarkJ.Bobak很酷的+1!我錯過了閱讀'scanf'!離成功只有一步之遙! –