2017-12-03 355 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; 
相关问题