Hey everybody!
I started learning C a few weeks ago, and I wanted to try and learn the underlying language features without using the foundation framework, so I've been dealing with strings by hand. It's been difficult to say the least, but it seems to have helped solidify some of the concepts of memory management and variable types (although in truth I'm still not sure how well I understand!). At any rate, everything was going smoothly until I ran into something which I cannot for the life of me debug. This may be a bit long winded, but I have tried to cut down on any superfluous information.
Essentially what I'm trying to do is get input from the user (via fgets), and then, based on what the user typed, execute commands. So, fgets saves the users input to a character array "gInput" (a global variable), and I check if it matches whatever command I want by invoking the following method. For example, one of my statements is:
Code:
if ( checkInput("north") || checkInput("n") ) { [currentPlayer move: "north"]; }
The checkInput method is...
Code:
int checkInput (char * check) {
int i = 0;
int same = 1; // assume they are the same. this may be disproven later.
extern char gInput[50];
if ( gInput[i] == '\n' || gInput[i] == '\0' ) { same = 0; } // so that no input does not return as the same
for ( i = 0; gInput[i] != '\n' && gInput[i] != '\0'; i++ ) { // until you find a newline or null char
if ( gInput[i] != check[i]) { same = 0; }
}
if ( check[i] != '\0' ) { same = 0;} // to prevent ea from returning as the same as east, etc.
if ( same == 1 ) { gMatched = 1; return 1;} else { return 0; }
}
Now, this works fine and well, however I needed something that would do more than simply tell me if two strings were the same. I needed the user to be able to input a command such as 'get short sword', and have something that would realize that the user was invoking the get command on the object short sword. To accomplish this, I wrote this. There are ultimately only going to be a limited number of commands, so I didn't mind parsing them manually via array[index] == 'letter', although is there a better way to do this? This method is invoked by this command...
Code:
if ( checkCommand() == "get") { get(currentPlayer); }
And the checkCommand() method is...
Code:
char* checkCommand () {
int i = 0;
extern char gInput[50];
extern char gSecondWord[50];
if ( gInput[0] == 'g' && gInput[1] == 'e' && gInput[2] == 't' && gInput[3] == ' ' ) {
gMatched = 1;
i = 4;
for ( i = 4; gInput[i] != '\n' && gInput[i] != '\0'; i++ ) {
gSecondWord[i-4] = gInput[i];
}
gSecondWord[i-4] = '\0';
return "get";
}
if ( gInput[0] == 'd' && gInput[1] == 'r' && gInput[2] == 'o' && gInput[3] == 'p' && gInput[4] == ' ') {
gMatched = 1;
i = 5;
for ( i = 5; gInput[i] != '\n' && gInput[i] != '\0'; i++) {
gSecondWord[i-5] = gInput[i];
}
gSecondWord[i-5] = '\0';
return "drop";
}
}
So basically, if the command parses get, then it runs the get method.. if parses drop, then it runs the drop method. (ultimately I will expand this to commands such as "look" and "fight", however I imagine this will be straightforward)
So here is where we run into the problem that I just cannot understand.
The get method works perfectly.
Code:
void get (Player * currentPlayer) {
extern char gResult[100];
sprintf(gResult, "There is nothing here by that name.");
extern Room *gRooms [10][10];
extern char gSecondWord[50];
char *secondWord;
sprintf(secondWord, "%s", gSecondWord);
char *itemName;
extern int times;
times = 0;
int done = 0;
for ( times = 0; times <= 9 && done == 0; times++ ) {
if ([gRooms[[currentPlayer retRow]][[currentPlayer retCol]] retItem]) {
itemName = [[gRooms[[currentPlayer retRow]][[currentPlayer retCol]] retItem] retName];
if (CheckStrings (itemName, secondWord) ) {
done = 1;
[currentPlayer claimThing: [gRooms[[currentPlayer retRow]][[currentPlayer retCol]] retItem]];
}
}
}
}
But the drop command is doing something weird. Everything seems to be pretty much the same as the get command, and yet if I remove one of the lines which I can't see as legitimately serving any purpose, I get a Bus Error (I have indicated which line via a comment in the code). With the line though, the code runs perfectly. I can pick up items, move to a new room, drop them, pick them up later.. it seems to be running fine.
Code:
void drop (Player * currentPlayer) {
extern char gResult[100];
sprintf(gResult, "You are carrying nothing by that name.");
extern char gSecondWord[50];
char *secondWord;
sprintf(secondWord, "%c", gSecondWord[0], gSecondWord[1], gSecondWord[2], gSecondWord[3], gSecondWord[4]);
// I don't understand why the above line should make a difference!
sprintf(secondWord, "%s", gSecondWord);
char *itemName;
extern int times;
times = 0;
int done = 0;
for ( times = 0; times <= 9 && done == 0; times++ ) {
if ([currentPlayer retItem]) {
itemName = [[currentPlayer retItem] retName];
if (CheckStrings (itemName, secondWord) ) {
done = 1;
[currentPlayer releaseThing: [currentPlayer retItem]];
}
}
}
}
I am befuddled. With the line, the program seems to run perfectly. Remove it though, and I get a bus error. The weird thing is, the get command works perfectly even without this strange command. I feel like my code must be unstable if I have to invoke work arounds like this!
Thank you very much for taking the time to read over this. Does anybody have any thoughts?