我有一个我写的命令行游戏,可以在本地运行,但在远程服务器上运行段错误。我还没有找到原因。
本地:
远程:
在某些地方显然存在聚集/显示可能连接的问题。
这是完整的计划。这个问题可能发生在第190行附近,就像可能的连接逻辑所在的那样。我觉得我的strncpy
行存在问题,因为那里有非常具体的内存操作,但我可能错了。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
struct stat st = {0};
const char * ROOM_NAMES[] = {"Water", "Fire", "Wind", "Earth", "Plasma", "DarkMatter", "Air", "Ice", "Rock", "Lava"};
int i,j;
char directory[20];
char *rooms[7];
int connections[7][7] = {0};
int totalMoves = 0;
char roomChoice[20];
char *movesRecord[100];
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void getRoomChoice() {
fflush(stdin);
scanf("%s", roomChoice);
fflush(stdin);
fflush(stdout);
}
void * getTime(void *arg) {
pthread_mutex_lock(&mutex);
FILE *file = fopen("currentTime.txt", "w");
time_t curtime;
struct tm *loc_time;
curtime = time (NULL);
loc_time = localtime (&curtime);
fprintf(file, "%s\n", asctime (loc_time));
// printf("\n%s\n", asctime (loc_time));
fclose(file);
pthread_mutex_unlock(&mutex);
}
void * createRooms() {
// Create directory
int pid = getpid();
char prefix[] = "eldridgt.";
sprintf(directory, "%s%d", prefix, pid);
if (stat(directory, &st) == -1) {
mkdir(directory, 0700);
}
// Create room files
for(i=0; i<7; i++) {
int random;
char filePath[100];
int connectionArr[10];
memset(connectionArr, 0, sizeof connectionArr);
random = rand() % 10; // Random number 0-9
if (connectionArr[random] == 0) { // If room not used
sprintf(filePath,"%s/%s", directory, ROOM_NAMES[random]);
FILE *file = fopen(filePath, "ab+");
fprintf(file, "ROOM NAME: %s\n", ROOM_NAMES[random]); // Add room name
fclose(file);
rooms[i] = ROOM_NAMES[random];
connectionArr[random] = 1; // Room has been used
}
}
return rooms;
}
void * createConnections() {
for(i=0; i<7; i++) {
int connectionCount = rand() % 4 + 3; // Random number 3-6
int currentCount = 0;
for(j=0; j<7; j++) {
currentCount = currentCount + connections[i][j];
}
while (currentCount < connectionCount+1) {
int random = rand() % 7;
while (random == i) {
random = rand() % 7; // If random == current, reset random
}
// Set connections between both rooms
connections[i][random] = 1;
connections[random][i] = 1;
currentCount++;
}
}
}
void * connectionsToFiles() {
for(i=0; i<7; i++) {
int connectionCount = 1;
for(j=0; j<7; j++) {
if(connections[i][j] == 1) {
char filePath[100];
sprintf(filePath,"%s/%s", directory, rooms[i]);
FILE *file = fopen(filePath, "ab+");
fprintf(file, "CONNECTION %d: %s\n", connectionCount, rooms[j]);
fclose(file);
connectionCount++;
}
}
}
}
void * roomTypesToFiles() {
for(i=0; i<7; i++) {
char filePath[100];
sprintf(filePath,"%s/%s", directory, rooms[i]);
FILE *file = fopen(filePath, "a");
switch(i) {
case 0 :
fprintf(file, "ROOM TYPE: START_ROOM\n");
break;
case 6 :
fprintf(file, "ROOM TYPE: END_ROOM\n");
break;
default :
fprintf(file, "ROOM TYPE: MID_ROOM\n");
}
fclose(file);
}
}
isEndRoom(idx) {
movesRecord[totalMoves - 1] = rooms[idx];
char filePath[100];
sprintf(filePath,"%s/%s", directory, rooms[idx]);
char roomType[20];
int lineNumber = 1;
FILE *file = fopen(filePath, "r");
int totaLines = 0;
char line[256];
while(fgets(line, sizeof line, file) != NULL) {
totaLines++; // Line count of room file
}
fclose(file);
file = fopen(filePath, "r");
while(fgets(line, sizeof line, file) != NULL) {
if(lineNumber == totaLines) {
int length = strlen(line) - 11;
strcpy(roomType, line+11);
roomType[length-1] = '\0';
}
lineNumber++;
}
// Check if this is the end room
if(strncmp(roomType, "END", 3) == 0) {
printf("YOU HAVE FOUND THE END ROOM. CONGRATULATIONS!\n");
printf("YOU TOOK %d STEPS. YOUR PATH TO VICTORY WAS:\n", totalMoves - 1);
for(i=1; i<totalMoves; i++) {
printf("%s\n", movesRecord[i]);
}
return 1; // End was reached
} else {
return 0; // End was not reached
}
}
void * playGame(idx) {
totalMoves++;
printf("\n");
if(isEndRoom(idx)) {
exit(0);
}
while(1) {
char filePath[100];
sprintf(filePath,"%s/%s", directory, rooms[idx]);
FILE *file = fopen(filePath, "r");
int totaLines = 0;
char line[100];
while(fgets(line, sizeof line, file) != NULL) {
totaLines++; // Line count of room file
}
fclose(file);
file = fopen(filePath, "r");
int lineNumber = 0;
char *roomChoices[6][20];
while(fgets(line, sizeof line, file) != NULL) { // Current room name
if(lineNumber == 0) {
char roomName[20];
int length = strlen(line) - 11;
strcpy(roomName, line+11);
roomName[length-1] = '\0';
printf("CURRENT LOCATION: %s\n", roomName);
}
else if(lineNumber == 1) { // First room choice option
printf("POSSIBLE CONNECTIONS: ");
fflush(stdout);
char roomName[20];
int length = strlen(line) - 14;
strcpy(roomName, line+14);
roomName[length-1] = '\0';
printf("%s", roomName);
strcpy(roomChoices[lineNumber - 1], roomName);
}
else if(lineNumber > 1 && lineNumber < totaLines - 1) { // Subsequent room choice options
printf(", ");
fflush(stdout);
char roomName[20];
int length = strlen(line) - 14;
strcpy(roomName, line+14);
roomName[length-1] = '\0';
printf("%s", roomName);
fflush(stdout);
strcpy(roomChoices[lineNumber - 1], roomName);
}
else {
printf(".");
fflush(stdout);
}
lineNumber++;
}
fclose(file);
printf("\nWHERE TO? >");
getRoomChoice(); // Get next room choice
if (strcmp(roomChoice, "time") == 0) {
pthread_t thread;
int rc = pthread_create(&thread, NULL, &getTime, NULL);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
pthread_mutex_lock(&mutex);
sleep(1);
FILE *file = fopen("currentTime.txt", "r");
char currentTime[25];
fgets(currentTime, sizeof currentTime, file);
printf("\n%s\n\n", currentTime);
pthread_mutex_unlock(&mutex);
} else {
for(i=0; i<totaLines-2; i++) {
if(strcmp(roomChoices[i], roomChoice) == 0) {
for(j=0; j<7; j++) {
if(strcmp(rooms[j], roomChoice) == 0) { // If the room is equal to roomChoice
playGame(j); // Make playGame call for new room
}
}
}
}
printf("\nHUH? I DON’T UNDERSTAND THAT ROOM. TRY AGAIN.\n\n");
fflush(stdout);
fflush(stdin);
}
}
}
int main() {
createRooms();
createConnections();
connectionsToFiles();
roomTypesToFiles();
playGame(0);
return 0;
}
答案 0 :(得分:0)
我也遇到了段错并试图修复代码。现在它确实在一些变化之后运行。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include <memory.h>
struct stat st = {0};
char *ROOM_NAMES[] = {"Water", "Fire", "Wind", "Earth", "Plasma", "DarkMatter", "Air", "Ice", "Rock", "Lava"};
int i, j;
char directory[20];
char *rooms[7];
int connections[7][7] = {0};
int totalMoves = 0;
char roomChoice[20];
char *movesRecord[100];
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void getRoomChoice() {
fflush(stdin);
scanf("%s", roomChoice);
fflush(stdin);
fflush(stdout);
}
void *getTime(void *arg) {
pthread_mutex_lock(&mutex);
FILE *file = fopen("currentTime.txt", "w");
time_t curtime;
struct tm *loc_time;
curtime = time(NULL);
loc_time = localtime(&curtime);
fprintf(file, "%s\n", asctime(loc_time));
// printf("\n%s\n", asctime (loc_time));
fclose(file);
pthread_mutex_unlock(&mutex);
}
void *createRooms() {
// Create directory
int pid = getpid();
char prefix[] = "eldridgt.";
sprintf(directory, "%s%d", prefix, pid);
if (stat(directory, &st) == -1) {
mkdir(directory, 0700);
}
// Create room files
for (i = 0; i < 7; i++) {
int random;
char filePath[100];
int connectionArr[10];
memset(connectionArr, 0, sizeof connectionArr);
random = rand() % 10; // Random number 0-9
if (connectionArr[random] == 0) { // If room not used
sprintf(filePath, "%s/%s", directory, ROOM_NAMES[random]);
FILE *file = fopen(filePath, "ab+");
fprintf(file, "ROOM NAME: %s\n", ROOM_NAMES[random]); // Add room name
fclose(file);
rooms[i] = ROOM_NAMES[random];
connectionArr[random] = 1; // Room has been used
}
}
return rooms;
}
void *createConnections() {
for (i = 0; i < 7; i++) {
int connectionCount = rand() % 4 + 3; // Random number 3-6
int currentCount = 0;
for (j = 0; j < 7; j++) {
currentCount = currentCount + connections[i][j];
}
while (currentCount < connectionCount + 1) {
int random = rand() % 7;
while (random == i) {
random = rand() % 7; // If random == current, reset random
}
// Set connections between both rooms
connections[i][random] = 1;
connections[random][i] = 1;
currentCount++;
}
}
}
void *connectionsToFiles() {
for (i = 0; i < 7; i++) {
int connectionCount = 1;
for (j = 0; j < 7; j++) {
if (connections[i][j] == 1) {
char filePath[100];
sprintf(filePath, "%s/%s", directory, rooms[i]);
FILE *file = fopen(filePath, "ab+");
fprintf(file, "CONNECTION %d: %s\n", connectionCount, rooms[j]);
fclose(file);
connectionCount++;
}
}
}
}
void *roomTypesToFiles() {
for (i = 0; i < 7; i++) {
char filePath[100];
sprintf(filePath, "%s/%s", directory, rooms[i]);
FILE *file = fopen(filePath, "a");
switch (i) {
case 0 :
fprintf(file, "ROOM TYPE: START_ROOM\n");
break;
case 6 :
fprintf(file, "ROOM TYPE: END_ROOM\n");
break;
default :
fprintf(file, "ROOM TYPE: MID_ROOM\n");
}
fclose(file);
}
}
int isEndRoom(int idx) {
movesRecord[totalMoves - 1] = rooms[idx];
char filePath[100];
sprintf(filePath, "%s/%s", directory, rooms[idx]);
char roomType[20];
int lineNumber = 1;
FILE *file = fopen(filePath, "r");
int totaLines = 0;
char line[256];
while (fgets(line, sizeof line, file) != NULL) {
totaLines++; // Line count of room file
}
fclose(file);
file = fopen(filePath, "r");
while (fgets(line, sizeof line, file) != NULL) {
if (lineNumber == totaLines) {
int length = strlen(line) - 11;
strcpy(roomType, line + 11);
roomType[length - 1] = '\0';
}
lineNumber++;
}
// Check if this is the end room
if (strncmp(roomType, "END", 3) == 0) {
printf("YOU HAVE FOUND THE END ROOM. CONGRATULATIONS!\n");
printf("YOU TOOK %d STEPS. YOUR PATH TO VICTORY WAS:\n", totalMoves - 1);
for (i = 1; i < totalMoves; i++) {
printf("%s\n", movesRecord[i]);
}
return 1; // End was reached
} else {
return 0; // End was not reached
}
}
void *playGame(int idx) {
totalMoves++;
printf("\n");
if (isEndRoom(idx)) {
exit(0);
}
while (1) {
char filePath[100];
sprintf(filePath, "%s/%s", directory, rooms[idx]);
FILE *file = fopen(filePath, "r");
int totaLines = 0;
char line[100];
while (fgets(line, sizeof line, file) != NULL) {
totaLines++; // Line count of room file
}
fclose(file);
file = fopen(filePath, "r");
int lineNumber = 0;
char roomChoices[6][20];
while (fgets(line, sizeof line, file) != NULL) { // Current room name
if (lineNumber == 0) {
char roomName[20];
int length = strlen(line) - 11;
strcpy(roomName, line + 11);
roomName[length - 1] = '\0';
printf("CURRENT LOCATION: %s\n", roomName);
} else if (lineNumber == 1) { // First room choice option
printf("POSSIBLE CONNECTIONS: ");
fflush(stdout);
char roomName[20];
int length = strlen(line) - 14;
strcpy(roomName, line + 14);
roomName[length - 1] = '\0';
printf("%s", roomName);
strcpy(roomChoices[lineNumber - 1], roomName);
} else if (lineNumber > 1 && lineNumber < totaLines - 1) { // Subsequent room choice options
printf(", ");
fflush(stdout);
char roomName[20];
int length = strlen(line) - 14;
strcpy(roomName, line + 14);
roomName[length - 1] = '\0';
printf("%s", roomName);
fflush(stdout);
strcpy(roomChoices[lineNumber - 1], roomName);
} else {
printf(".");
fflush(stdout);
}
lineNumber++;
}
fclose(file);
printf("\nWHERE TO? >");
getRoomChoice(); // Get next room choice
if (strcmp(roomChoice, "time") == 0) {
pthread_t thread;
int rc = pthread_create(&thread, NULL, &getTime, NULL);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
pthread_mutex_lock(&mutex);
sleep(1);
FILE *file = fopen("currentTime.txt", "r");
char currentTime[25];
fgets(currentTime, sizeof currentTime, file);
printf("\n%s\n\n", currentTime);
pthread_mutex_unlock(&mutex);
} else {
for (i = 0; i < totaLines - 2; i++) {
if (strcmp(roomChoices[i], roomChoice) == 0) {
for (j = 0; j < 7; j++) {
if (strcmp(rooms[j], roomChoice) == 0) { // If the room is equal to roomChoice
playGame(j); // Make playGame call for new room
}
}
}
}
printf("\nHUH? I DON’T UNDERSTAND THAT ROOM. TRY AGAIN.\n\n");
fflush(stdout);
fflush(stdin);
}
}
}
int main() {
createRooms();
createConnections();
connectionsToFiles();
roomTypesToFiles();
playGame(0);
return 0;
}
测试
rooms
CURRENT LOCATION: Earth
POSSIBLE CONNECTIONS: th, Air, Ice, DarkMatter, Earth, DarkMatter, Earth, Air, DarkMatter, DarkMatter, RT_ROOM.
WHERE TO? >Air
YOU HAVE FOUND THE END ROOM. CONGRATULATIONS!
YOU TOOK 1 STEPS. YOUR PATH TO VICTORY WAS:
Air
Process finished with exit code 0