2017-12-03 354 views
1

輸出應該像這樣打印出來,當船員挖掘整個空間值「s」時,它將變爲值「T」,並且如果可以幫助創建一個打印地圖結構的函數,而不是每次都使用for循環我們將不勝感激太!:我將如何替換二維數組結構中的一個值爲另一個值和c中的二維數組結構的打印函數?

Crew Dig Carry
1 3 1
2 2 5
3 4 1
4 1 3

你想在哪裏送船員1?
4s 1s 3s
1s 2s 3s
1s 5s 1s

您已刪除所有的沙子從這一節!

您想將船員2發送至哪裏?
4s 1s 1T
1s 2s 3s
1s 5s 1s

我到目前爲止有:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NUMCREW 4  
#define MAXHOUR 8  
#define MINHOUR 1  
#define ROW 3  
#define COL 3  


struct pirate { 
    int dig; 
    int carry; 
}; 

struct map { 
    int sand; 
    int treasure; 
}; 

void printcrew(struct pirate * pirate_data); 
void print(struct map * map_data);  


int main() { 
char filename[20]; 
int hour=8; 
int crew=0; 
int i, j, x, y; 
int space; 
struct map map_data[ROW][COL]; 
struct pirate pirate_data[NUMCREW]; 
FILE * ifp; 

printf("You have arrived at Treasure Island!\n"); 
printf("What is the name of your map?\n"); 
scanf("%s", filename); 

ifp = fopen(filename, "r"); 



for (i=0; i<ROW; i++){ 
    for (j=0; j<COL; j++) { 
     fscanf(ifp, "%d %d", &map_data[i][j].sand, &map_data[i][j].treasure); 
    } 
} 


for (i=0; i<NUMCREW; i++) { 
    fscanf(ifp, "%d", &pirate_data[i].dig); 
    fscanf(ifp, "%d", &pirate_data[i].carry); 
} 

fclose(ifp); 
for (hour=8; hour >= MINHOUR; hour--) { 
    printf("\nYou have %d hours left to dig up the treasure.\n", hour); 
    printcrew(pirate_data); 
    printf("\n"); 

    for (crew=0; crew<NUMCREW; crew++){ 
     printf("Where would you like to send crew member %d?\n", crew+1); 

     for(i=0; i<ROW; i++) { 
      for (j=0; j<COL; j++) { 
      printf("%ds\t", map_data[i][j].sand); 
       if (map_data[i][j].sand == 0) { 
        printf("%dT\t", map_data[i][j].treasure); 
      } 
     } 
      printf("\n"); 
      } 
      scanf("%d %d", &x, &y); 
      map_data[x-1][y-1].sand = map_data[x-1][y-1].sand - pirate_data[crew].dig; 
     } 
    } 

return 0; 
} 

void printcrew(struct pirate * pirate_data) { 
int i;` 

printf("Crew \t Dig \t Carry \n"); 
for (i=0; i<NUMCREW; i++) 
    printf("%d \t %d \t %d \n", i+1, pirate_data[i].dig, pirate_data[i].carry); 

return; 

} 

void print(struct map * map_data) { 
int i, j; 

for(i=0; i<ROW; i++) { 
    for (j=0; j<COL; j++) { 
     printf("%ds\t", map_data[i][j].sand); 
    } 
    printf("\n"); 
} 

return; 

}

我的輸出保持出來,如:
您希望發送船員1的位置?
4s 1s 3s
1s 2s 3s
1s 5s 1s

您希望發送船員2的哪個位置?
4s 1s 0s 1T
1s 2s 3s
1s 5s 1s

您想發送船員3的哪個位置?
4s 1s 0s 1T
1s 0s 1T 3s
1s 5s 1s

關於打印的結構地圖功能我不斷收到以下錯誤:
在功能上「打印」:|
錯誤:下標值既不是數組也不是矢量|

回答

0

在發佈的代碼中似乎有一個錯字;在printcrew()函數中有一個流浪的字符。應該看到一個編譯器警告,並且所有的編譯器警告都應該被修復。

int i;` 

關於print()函數的問題,函數原型是錯誤的。在包含函數調用的大多數表達式中,數組衰減爲指向其第一個元素的指針。現在,像struct map map_data[ROW][COL]這樣的二維數組實際上是一組元素的ROW數組。也就是說,這個數組的每一行都有類型struct map map_data[COL]。當指針發生衰減時,結果是一個指向第一個元素的指針,它是一個指向數組的指針(不是指向mapstruct的指針)。用於表示這種指向數組的指針的語法是:struct map (*ptr)[COL]。因此,該函數的原型應該是:

void print(struct map (*map_data)[COL]); 

若要更新顯示,以顯示找到寶藏修復該問題,請檢查是否寶藏之前印刷沙發現,只有打印沙子,如果寶未找到:

for(i=0; i<ROW; i++) { 
    for (j=0; j<COL; j++) { 
     int sand = map_data[i][j].sand; 
     if (sand > 0) { 
      printf("%ds\t", sand); 
     } else { 
      printf("%dT\t", map_data[i][j].treasure); 
     } 
    } 
    printf("\n"); 
} 

關於輸入驗證的一些意見是按順序。使用%s%[]指令和scanf()系列函數讀取字符串輸入時,始終指定最大寬度;如果不這樣做可能會導致緩衝區溢出和未定義的行爲。

請注意,scanf()和家人返回成功分配的數量;應檢查此值以確保輸入符合預期。在發佈的代碼中,如果用戶狡猾地通過鍵盤發送文件結束信號,scanf()會在未做任務的情況下返回。由於filename[]未初始化,因此在使用filename時會導致未定義的行爲。相反,請嘗試如下所示:

if (scanf("%19s", filename) < 1) { 
    fprintf(stderr, "Input error\n"); 
    exit(EXIT_FAILURE); 
} 

驗證打開文件的嘗試是否成功也非常重要。當代碼繼續打開時,如果文件無法打開,就像它們打開成功一樣,則會出現未定義的行爲fopen()失敗時返回一個空指針:

ifp = fopen(filename, "r"); 
if (ifp == NULL) { 
    fprintf(stderr, "Unable to open file %s\n", filename); 
    exit(EXIT_FAILURE); 
} 

道德這個故事是,你應該檢查值從它返回一個有意義的值的任何函數返回。

有因未能驗證輸入這裏麻煩進一步潛在:

scanf("%d %d", &x, &y); 
map_data[x-1][y-1].sand = map_data[x-1][y-1].sand - pirate_data[crew].dig; 

如果用戶輸入非數字輸入,沒有值存儲在相關聯的變量。充其量,由於使用先前存儲的值,這導致令人驚訝的行爲。最糟糕的是,當關聯變量的值不確定時(例如未初始化),這會導致未定義的行爲。此外,用戶可能會在此處輸入一個非正數,導致負數組索引和未定義的行爲。或者用戶可能輸入太大的值,導致嘗試超出範圍數組訪問和未定義的行爲。此外,sand成員即使在負值時也會遞減;這可能會也可能不是所希望的,但是對於不太可能的勤勞盜版者和惡意用戶的組合,可能會導致帶有符號整數溢出的未定義行爲。

驗證所有輸入,特別是永遠不可信的用戶輸入,始終被視爲惡意。檢查scanf()返回的值以確保輸入至少與預期大致相同,並檢查輸入值是否在可接受的範圍內。輸入處理的不好取決於程序員;一種選擇是再次提示輸入正確:

while (scanf("%d %d", &x, &y) < 2 
     || x < 1 
     || x > COL 
     || y < 1 
     || y > ROW) { 
    printf("Please enter numbers in the ranges [1, %d] [1, %d]\n", 
      ROW, COL); 
} 
map_data[x-1][y-1].sand = map_data[x-1][y-1].sand - pirate_data[crew].dig; 
相關問題