【问题标题】:How would I replace a value in a 2d array structure for a different value and printing function for the 2d array structure in c?如何将二维数组结构中的值替换为 c 中二维数组结构的不同值和打印函数?
【发布时间】:2017-12-03 05:20:49
【问题描述】:

当工作人员挖掘出 value"s" 的整个空间时,输出应该像这样打印出来,它会更改为 value"T",如果您可以帮助创建一个打印地图结构的函数,而不是每次都使用 for 循环我们也将不胜感激!:

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

1 3

您已移除此部分的所有沙子!

你想把船员 2 送到哪里?
4s 1s 1T
1s 2s 3s
1s 5s 1s

2 2

我目前拥有的:
#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

1 3
你想把船员 2 送到哪里?
4s 1s 0s 1T
1s 2s 3s
1s 5s 1s

2 2
您想把 3 号机组人员送到哪里?
4s 1s 0s 1T
1s 0s 1T 3s
1s 5s 1s

至于打印结构映射函数,我不断收到以下错误:
在函数“打印”中:|
错误:下标值既不是数组也不是指针也不是向量|

【问题讨论】:

    标签: c arrays pointers struct


    【解决方案1】:

    发布的代码中似乎有错字; printcrew() 函数中有一个杂散的 ` 字符。应该看到一个编译器警告,并且应该修复所有编译器警告。

    int i;`
    

    关于print()函数的问题,函数原型是错误的。在大多数表达式中,包括函数调用,数组衰减为指向其第一个元素的指针。现在,像struct map map_data[ROW][COL] 这样的二维数组实际上是由ROW 数组组成的COL 元素数组。也就是说,这个数组的每一行都有类型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");
    }
    

    一些关于输入验证的 cmets 是有序的。使用带有scanf() 系列函数的%s%[] 指令读取字符串输入时,始终指定最大宽度;不这样做可能会导致缓冲区溢出和未定义的行为。

    注意scanf() 和family 返回成功分配的次数;应检查此值以确保输入符合预期。在发布的代码中,如果用户巧妙地从键盘发出文件结束信号,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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      • 2015-03-15
      • 2020-06-25
      • 1970-01-01
      • 1970-01-01
      • 2012-02-28
      相关资源
      最近更新 更多