C에서 간단한 텍스트 모험 프로그램을 작성하려고합니다. 각 방의 이름/설명을 설정할 때 strcpy()에 문제가 있습니다. 게임 (room_setup() 참조). 처음 두 (NO_ROOM 및 KITCHEN)를 제외한 모든 객실의 이름/설명을 설정합니다. 간단한 테스트로 일부 문자열에서는 strcpy()가 작동하지 않지만 다른 문자열에서는 작동하지 않습니다.
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#define DIRS 4
#define DEBUG 0
#define MAX_INPUT_LENGTH 100
// defines numeric values for each direction
typedef enum {NORTH, EAST, SOUTH, WEST} en_dirs;
// defines numeric values for each room
typedef enum {
KITCHEN,
PANTRY,
HALLWAY_1,
HALLWAY_2,
TROLLS_DOMAIN,
EMPTY_ROOM_1,
EMPTY_ROOM_2,
EXIT,
NO_ROOM
} en_rooms;
// defines numeric values for each item
typedef enum{
APPLE,
KEY,
NO_ITEM
} en_items;
// defines a struct type to store room data
typedef struct room{
char name[100];
char desc[100];
en_dirs around[DIRS];
} Room;
// defines a struct type to store item data
typedef struct items{
char name[100];
char desc[100];
} Item;
void str_read(char *s); // read string from console, point s to it
void str_upper(char *s); // convert string to upper case
void room_setup(Room *r); // fill info about rooms into r array
void item_setup(Item *i); // fill info about items into i array
int main(void){
char input[MAX_INPUT_LENGTH];
char *verb, *noun;
// arrays to store room and item info. NO_**** is always the final element
// in their respective enums, so the size of the array will never be larger
// than necessary.
Room rooms[NO_ROOM];
Item items[NO_ITEM];
room_setup(rooms); // fill rooms array with info
item_setup(items); // fill items array with info
en_rooms currentRoom = KITCHEN; // set the starting room to the kitchen
// main game loop
while(1){
// print current room name + description
printf("-- %s --\n", rooms[currentRoom].name);
printf("%s\n", rooms[currentRoom].desc);
printf("\n> ");
// read input and convert it to upper case
str_read(input);
str_upper(input);
if(DEBUG){
printf("Input: %s\n", input);
printf("Length: %d\n", strlen(input));
}
// split input into two pieces (expects max of two words, for now)
verb = strtok(input, " ");
noun = strtok(NULL, " ");
if(DEBUG){
printf("Verb: %s\n", verb);
printf("Noun: %s\n", noun);
}
/*
if(strcmp(input, "NORTH") == 0 && rooms[currentRoom].around[NORTH] != NO_ROOM){
currentRoom = rooms[currentRoom].around[NORTH];
}
*/
}
return 0;
}
// points s to new string. clears stdin if user has input more than
// MAX_USER_INPUT characters.
void str_read(char *s){
fgets(s, MAX_INPUT_LENGTH, stdin); // point s to user input from stdin
// clear extra characters from stdin, if the user has input more than
// MAX_INPUT_LENGTH characters.
if(!strchr(s, '\n')){ // newline does not exist
while(fgetc(stdin) != '\n'); // discard until newline
}
}
// converts string s to upper case
void str_upper(char *s){
int i;
char c;
for(i = 0; i < strlen(s); i++){
s[i] = toupper(s[i]);
}
}
// fills the array r with info on each room.
void room_setup(Room *r){
strcpy(r[NO_ROOM].name, "Nothing there.");
strcpy(r[NO_ROOM].name, "Description");
r[NO_ROOM].around[NORTH] = NO_ROOM;
r[NO_ROOM].around[EAST] = NO_ROOM;
r[NO_ROOM].around[SOUTH] = NO_ROOM;
r[NO_ROOM].around[WEST] = NO_ROOM;
strcpy(r[KITCHEN].name, "Kitchen");
strcpy(r[KITCHEN].desc, "This is the kitchen.");
r[KITCHEN].around[NORTH] = NO_ROOM;
r[KITCHEN].around[EAST] = PANTRY;
r[KITCHEN].around[SOUTH] = NO_ROOM;
r[KITCHEN].around[WEST] = NO_ROOM;
strcpy(r[HALLWAY_1].name, "Hallway");
strcpy(r[HALLWAY_1].desc, "A long hallway.");
r[HALLWAY_1].around[NORTH] = HALLWAY_2;
r[HALLWAY_1].around[EAST] = NO_ROOM;
r[HALLWAY_1].around[SOUTH] = KITCHEN;
r[HALLWAY_1].around[WEST] = TROLLS_DOMAIN;
strcpy(r[TROLLS_DOMAIN].name, "Troll's Domain");
strcpy(r[TROLLS_DOMAIN].desc, "You see a Troll.");
r[TROLLS_DOMAIN].around[NORTH] = NO_ROOM;
r[TROLLS_DOMAIN].around[EAST] = HALLWAY_1;
r[TROLLS_DOMAIN].around[SOUTH] = EMPTY_ROOM_1;
r[TROLLS_DOMAIN].around[WEST] = NO_ROOM;
strcpy(r[EMPTY_ROOM_1].name, "Empty Room");
strcpy(r[EMPTY_ROOM_1].desc , "An empty room. There was no reason to come here.");
r[EMPTY_ROOM_1].around[NORTH] = TROLLS_DOMAIN;
r[EMPTY_ROOM_1].around[EAST] = NO_ROOM;
r[EMPTY_ROOM_1].around[SOUTH] = NO_ROOM;
r[EMPTY_ROOM_1].around[WEST] = NO_ROOM;
strcpy(r[HALLWAY_2].name, "Hallway"); //hallway 2
strcpy(r[HALLWAY_2].desc, "A long hallway.");
r[HALLWAY_2].around[NORTH] = EXIT;
r[HALLWAY_2].around[EAST] = EMPTY_ROOM_2;
r[HALLWAY_2].around[SOUTH] = NO_ROOM;
r[HALLWAY_2].around[WEST] = NO_ROOM;
strcpy(r[EMPTY_ROOM_2].name, "Empty Room");
strcpy(r[EMPTY_ROOM_2].desc , "An empty room.");
r[EMPTY_ROOM_2].around[NORTH] = NO_ROOM;
r[EMPTY_ROOM_2].around[EAST] = NO_ROOM;
r[EMPTY_ROOM_2].around[SOUTH] = NO_ROOM;
r[EMPTY_ROOM_2].around[WEST] = HALLWAY_2;
strcpy(r[EXIT].name, "Exit");
strcpy(r[EXIT].desc, "You win lol");
r[EXIT].around[NORTH] = NO_ROOM;
r[EXIT].around[EAST] = NO_ROOM;
r[EXIT].around[SOUTH] = HALLWAY_2;
r[EXIT].around[WEST] = NO_ROOM;
}
// fills the array i with info on each item.
void item_setup(Item *i){
strcpy(i[APPLE].name, "Apple");
strcpy(i[APPLE].desc, "A bright red apple.");
strcpy(i[KEY].name, "Key");
strcpy(i[NO_ITEM].name, "A silver key.");
strcpy(i[NO_ITEM].name, "");
strcpy(i[NO_ITEM].desc, "");
}
, 나는 while 루프 동안 currentRoom 증가를 만들고,이 출력을했다 :
-- --
>
-- --
>
-- Hallway --
A long hallway.
>
-- Hallway --
A long hallway.
>
-- Troll's Domain --
You see a Troll.
>
-- Empty Room --
An empty room. There was no reason to come here.
>
-- Empty Room --
An empty room.
>
-- Exit --
You win lol
NO_ROOM과 부엌이 보인다 구조체에 복사 자신의 정보를 없었어요. 누구든지 제가 잘못 가고있는 곳에서 운동 할 수있게 도와 줄 수 있습니까?
"일부 문자열에서는 strcpy()가 작동하지 않지만 다른 문자열에서는 작동하지 않습니다"- 그래서 어떤 문자열에서도 작동하지 않습니까? 또는 그것이 작동하는 방법을 알았 으면 문자열에서 작업 중일 수 있습니까? 나는 다른 정보와 함께 [ask]가 요구하는대로 [mcve]라는 코드의 벽을 볼 수 있습니다. – Olaf
코드를 컴파일해서는 안됩니다. 'around' 멤버는'en_dirs' 타입이지만'en_rooms'을 가지고 있습니다. –
@DavidSchwartz 지적 해 주셔서 감사합니다. 하지만 슬프게도 여전히 'en_rooms'로 바뀌면 똑같은 문제가 발생합니다. – Sato