C++ string comparison statement problem

edited August 2005 in Internet & Media
Hi, I am ne to this forum, and have come seeking help. I am fairly new to programming and am having a problem with string comparison, in the following code, i have a string called "action" defined in one function, and then go to compare it in the function called reaction. even though the string may be one of the choices, it ignores it and skips straight to my else statement. If anyone can get back to me on this, thanks, its greatly appreciated, btw, i have already had some higher level programmers look into it, and they couldnt figure it out.

Oh just a note, becaue i move this project around, i have the include folder in my project folder, for easy access.

[php]/* MUD test
Kayne Raymond */

#include "include\iostream.h"
#include "include\string.h"
#include "include\conio.h"

//Global Variable Declarations

int locationx = 20, locationy = 20, firsttime = 1, GameRunning = 1, DisplayLocation = 1;
String action;
String name;

//

void Action(String action)
{
cout << "What will you do?";
getline(cin, action);
cout << endl;
}

//

void Terminate(int GameRunning)
{
cout << endl;
cout << "You have choose to quit the game. Thank you for playing.";
cout << endl;
GameRunning = 0;
}

//

void Location(int GameRunning, int firsttime, int locationx, int locationy)
{
if ((locationx == 20) && (locationy == 20)){

cout << "You look around to see that your are in a clearing,\n";
cout << "surrounded by a dark forest. It is fairly dark out,\n";
cout << "and you guess it is late evening.\n";
cout << "You can travel any direction.\n\n";
cout << "Type help to see how to use commands.\n\n";
}
else{
cout << "Error, out of bounds, will now terminate...";
GameRunning =0;
}
}


//

void Introduction()
{
cout << "
The MUD game
\n";
cout << "Thank you for trying \"The MUD game\"! If you find\n";
cout << "any bugs, please tell me. Thanks again.\n\n";
cout << "________________________________________________\n\n";
}

//

void Reaction(String action, int GameRunning)
{
if(((action == "north") || (action == "North") || (action == "n") || (action == "N"))){
locationx++;
DisplayLocation = 1;
}
else if (((action == "south") || (action == "South") || (action == "s") || (action == "S"))){
locationx--;
DisplayLocation = 1;
}
else if (((action == "east") || (action == "East") || (action == "e") || (action == "E"))){
locationy++;
DisplayLocation = 1;
}
else if (((action == "west") || (action == "West") || (action == "w") || (action == "W"))){
locationy--;
DisplayLocation = 1;
}
else if (((action == "exit") || (action == "Exit"))){
Terminate(GameRunning);
}
else if (((action == "help") || (action == "Help"))){
cout << "You have asked for help.\n";
cout << "There are few commands right now during development:\n";
cout << "Use the corresponding letter or word for the direction you would\n";
cout << "like you to move. Ex. N for north, or s for south, or west for west.\n";
cout << "There are also commands for items, such as picking something up, or\n";
cout << "using an item you posses. This will be incorporated eventually.\n";
cout << "Type exit or Exit to quit the program\n\n";
}
else
{
cout << "That is not an applicable action. Please type help to see commands.\n\n";
}
}

//

int main()
{
Introduction();
do{
if(DisplayLocation == 1){
Location(GameRunning, firsttime, locationx, locationy);
DisplayLocation =0;
}
Action(action);
Reaction(action, GameRunning);
}while (GameRunning == 1);
return(0);
}[/php]

Comments

  • NosferatuNosferatu Arizona
    edited March 2005
    Hey,

    You can't use == to compare strings. You have to use a function like strcmp() or strcmpi() which is case-insensitive. These functions return 0 when the two strings passed to them are equal. For example


    strcmp("test","test") returns 0 (they are the same), strcmpi("test","TeSt") returns 0 (they are the same when you ignore case) but strcmp("test","TeSt") returns 1 (they are different when you take case into account).

    so use a statement like
    If ((!(strcmpi(action,"north")) || (!(strcmpi(action,"n"))) {
      locationx++;
      DisplayLocation = 1;
    }
    
    or
    If ((strcmpi(action,"north")==0) || (strcmpi(action,"n")==0)) {
      locationx++;
      DisplayLocation = 1;
    }
    

    which both give the same result.
  • edited March 2005
    WOW, that was a fast reply, thanks, i really really appreciate the help.
    You all have a good night.
  • edited March 2005
    okay, i realised that my other string library doesnt support that, so i switched over to the included one in VC6, only to find i really dont know how to declare a string with it, my errors are as the following:

    G:\MUD test\main.cpp(11) : error C2146: syntax error : missing ';' before identifier 'action'
    G:\MUD test\main.cpp(11) : error C2501: 'string' : missing storage-class or type specifiers
    G:\MUD test\main.cpp(11) : fatal error C1004: unexpected end of file found

    the code is the same as before, except my string library declaration says "include\string.h" to refer to the microsoft string library. again, i am new, i dont know any better...
  • edited March 2005
    Sorry ignore that last post, Ive figured some things out but still have some errors...
    with that strcmpi and strcmp, i get errors telling me a cant convert a char pointer to a string.... my code is idetical to above.. except for my reaction function...

    [php]void Reaction(String action, int GameRunning)
    {
    if((strcmpi(action,"north") == 0) || (strcmpi(action,"North") == 0) || (strcmpi(action,"n") == 0) || (strcmpi(action,"N") == 0)){
    locationx++;
    DisplayLocation = 1;
    }
    else if ((strcmpi(action,"south") == 0) || (strcmpi(action,"South") == 0) || (strcmpi(action,"s") == 0) || (strcmpi(action,"S") == 0)){
    locationx--;
    DisplayLocation = 1;
    }
    else if ((strcmpi(action,"east") == 0) || (strcmpi(action,"East") == 0) || (strcmpi(action,"e") == 0) || (strcmpi(action,"E") == 0)){
    locationy++;
    DisplayLocation = 1;
    }
    else if ((strcmpi(action,"West") == 0) || (strcmpi(action,"West") == 0) || (strcmpi(action,"w") == 0) || (strcmpi(action,"W") == 0)){
    locationy--;
    DisplayLocation = 1;
    }
    else if ((strcmpi(action,"exit") == 0) || (strcmpi(action,"Exit") == 0)){
    Terminate(GameRunning);
    }
    else if ((strcmpi(action,"help") == 0) || (strcmpi(action,"Help") == 0)){
    cout << "You have asked for help.\n";
    cout << "There are few commands right now during development:\n";
    cout << "Use the corresponding letter or word for the direction you would\n";
    cout << "like you to move. Ex. N for north, or s for south, or west for west.\n";
    cout << "There are also commands for items, such as picking something up, or\n";
    cout << "using an item you posses. This will be incorporated eventually.\n";
    cout << "Type exit or Exit to quit the program\n\n";
    }
    else
    {
    cout << "That is not an applicable action. Please type \"help\" to see commands.\n\n";
    }
    }[/php]



    When compiling, i get the following error, 20 times, one for each strcmpi Quoted:

    G:\MUD test\main.cpp(66) : error C2664: 'strcmpi' : cannot convert parameter 1 from 'class String' to 'const char *'
    No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called




    BTW I just want to say thanks again for the help... Very appreciated. :)
  • primesuspectprimesuspect Beepin n' Boopin Detroit, MI Icrontian
    edited March 2005
    Welcome to short-media :)

    When you post code, it may be helpful to surround the entire code block with the [ PHP ] tags, like this:

    [PHP]this would be code[/PHP]
  • edited March 2005
    okay, so is it like

    [php]
    code here
    [/php]
  • edited March 2005
    ah i see
  • edited March 2005
    Alright, after logic kicked in, i figured i should just make the strings char * and then it should work...
  • edited March 2005
    w/e, i dont know, if anyone can give me a suggestion some time.... i give up for tonight, i have no experience with char * and using them...
  • edited March 2005
    any suggestion for comparing strings, or char *.... thanks
  • edited March 2005
    Okay, call me annoying, but... i finally figured something out... i converted the strings to char arrays... this actually allows the source code to compile, but, when it goes to link, i get the following

    [php]
    main.obj : error LNK2001: unresolved external symbol "char * action" (?action@@3PADA)
    Debug/MUD test.exe : fatal error LNK1120: 1 unresolved externals
    Error executing link.exe.
    [/php]

    my entire project code is the following:

    [php]
    /* MUD test
    Kayne Raymond */

    #include "include\iostream.h"
    #include "include\string.h"
    #include "include\conio.h"

    //Global Variable Declarations

    int locationx = 20, locationy = 20, firsttime = 1, GameRunning = 1, DisplayLocation = 1;
    char action[];

    //

    void Action(char action[])
    {
    cout << "What will you do?";
    cin >> action;
    cout << endl;
    }

    //

    void Terminate(int GameRunning)
    {
    cout << endl;
    cout << "You have choose to quit the game. Thank you for playing.";
    cout << endl;
    GameRunning = 0;
    }

    //

    void Location(int GameRunning, int firsttime, int locationx, int locationy)
    {
    if ((locationx == 20) && (locationy == 20)){

    cout << "You look around to see that your are in a clearing,\n";
    cout << "surrounded by a dark forest. It is fairly dark out,\n";
    cout << "and you guess it is late evening.\n";
    cout << "You can travel any direction.\n\n";
    cout << "Type help to see how to use commands.\n\n";
    }
    else{
    cout << "Error, out of bounds, will now terminate...";
    GameRunning =0;
    }
    }


    //

    void Introduction()
    {
    cout << "
    The MUD game
    \n";
    cout << "Thank you for trying \"The MUD game\"! If you find\n";
    cout << "any bugs, please tell me. Thanks again.\n\n";
    cout << "________________________________________________\n\n";
    }

    //

    void Reaction(char action[], int GameRunning)
    {
    if((strcmpi(action,"north") == 0) || (strcmpi(action,"North") == 0) || (strcmpi(action,"n") == 0) || (strcmpi(action,"N") == 0)){
    locationx++;
    DisplayLocation = 1;
    }
    else if ((strcmpi(action,"south") == 0) || (strcmpi(action,"South") == 0) || (strcmpi(action,"s") == 0) || (strcmpi(action,"S") == 0)){
    locationx--;
    DisplayLocation = 1;
    }
    else if ((strcmpi(action,"east") == 0) || (strcmpi(action,"East") == 0) || (strcmpi(action,"e") == 0) || (strcmpi(action,"E") == 0)){
    locationy++;
    DisplayLocation = 1;
    }
    else if ((strcmpi(action,"West") == 0) || (strcmpi(action,"West") == 0) || (strcmpi(action,"w") == 0) || (strcmpi(action,"W") == 0)){
    locationy--;
    DisplayLocation = 1;
    }
    else if ((strcmpi(action,"exit") == 0) || (strcmpi(action,"Exit") == 0)){
    Terminate(GameRunning);
    }
    else if ((strcmpi(action,"help") == 0) || (strcmpi(action,"Help") == 0)){
    cout << "You have asked for help.\n";
    cout << "There are few commands right now during development:\n";
    cout << "Use the corresponding letter or word for the direction you would\n";
    cout << "like you to move. Ex. N for north, or s for south, or west for west.\n";
    cout << "There are also commands for items, such as picking something up, or\n";
    cout << "using an item you posses. This will be incorporated eventually.\n";
    cout << "Type exit or Exit to quit the program\n\n";
    }
    else
    {
    cout << "That is not an applicable action. Please type \"help\" to see commands.\n\n";
    }
    }

    //

    int main()
    {
    Introduction();
    do{
    if(DisplayLocation == 1){
    Location(GameRunning, firsttime, locationx, locationy);
    DisplayLocation =0;
    }
    Action(action);
    Reaction(action, GameRunning);
    }while (GameRunning == 1);
    return(0);
    }
    [/php]

    Btw, i am soooo sorry for flooding this... i could not find another forum with any answers, and i am bad at asking a question, and then figuring it out and needing to answer a new one...
  • TheBaronTheBaron Austin, TX
    edited March 2005
    that compiles fine for me. just so you know, char* action and char action[] is doing exactly the same thing
  • edited March 2005
    Really, yeah i dont know much. Although i know i ahve had problems with it just being the project workspace before..

    Edit: I created a new project and workspace just too see, but for some reason i get the same linking error, what compiler are you using? i have vc++
  • TheBaronTheBaron Austin, TX
    edited March 2005
    i used codewarrior and g++, both worked fine
  • edited March 2005
    yeah thats really wierd then...
  • NosferatuNosferatu Arizona
    edited March 2005
    @kraymond,

    you don't need to compare W and w or West and west, the same for the others as well. strcmpi() ignores the case, so when it does strcmpi(action,"w") it will match W and w, and if you do strcmpi(action,"west") then it will match West, west, WEST, WeST, WeSt, WesT, and so on. To the code, all those will be the same.
  • edited March 2005
    alright thanks, but i still need help with my link error... lol
  • sharkydartsharkydart KY Icrontian
    edited March 2005
    i have a few comments to help you out here.

    first of all, you CAN compare String objects. The reason why it didn't work before was because you can't compare a String object to a literal string with "==", without overloading the "==" operator. However, you can use the member functions of a string object (use the MSDN library for reference if you aren't sure about something). use String.Equals(String). for example:

    void Reaction(String action, int GameRunning)
    {
    action = action.ToLower();

    if(action.Equals("north") || action.Equals("n"))
    ...
    }

    as far as your program goes, you should think about changing your design to be object-oriented. i know you say you are new, so you should start thinking about your ideas this way. for example, you could create a struct to store all player info together, conveniently:

    Struct player
    {
    String name;
    String last_move; //the more descriptive the name, the better
    int location[20][20]; //...i can't remember if this syntax is correct
    }player_first;
    player_first.name = "Bob";
    player_first.name.ToLower();
    ...

    look into using Classes and Structs.

    one last thing - look into reading from files. the way i would do this; create text files with what you want to display when the player takes certain actions. write a function that reads and displays a text file. that way, you don't have to edit NEARLY so much when you want to add or remove descriptive text segments. then, just call the function and send it a string representing the name of the text file.


    *** edit - if you can help it, use less global variables and pass by reference instead of value. at least make variables "protected"
  • GHoosdumGHoosdum Icrontian
    edited March 2005
    Excellent ideas, sharky! BTW - it's nice to see you posting here!
  • Yui-IkariYui-Ikari edmonton
    edited August 2005
    Hi, im new in here, this is my first post. Well , i was wondering why it wont let me compara 2 strings with " == "... im using string class :S
    here is the code ^_^..
    "SScory->m_SPlayers[playernumber].m_cName) == (SScory->m_SPlayers[ui].m_cName"
    #include <iostream>
    #include<cctype>
    #include<string.h>
    #include "Structs.h"
    using namespace std;
     struct SPlayer
    {
     stringr m_cName ;
     int m_Score [18];
    };
    
    struct SScoreCard
    {
    	string m_Course ;
    	int m_Holes [18];
    	SPlayer m_SPlayers [4];
    };
    void AddPlayer (SScoreCard * SScory, char * cChar);
    int  main ()
    {	
    
    SScoreCard STempScore;
    AddPlayer(&STempScore,"Player4");
    cin.get();
    return 0;
    }
    void AddPlayer (SScoreCard * SScory, char * cChar)
    {	int playernumber=6;
    	for (int i=0; i<4;i++)
    	{
    		if (SScory->m_SPlayers[i].m_cName[0]==NULL)
    		{
    		   playernumber=i;
    		    break;
    		}
    	}
    
        for (unsigned int ui=0;ui<3;ui++)
    	{
    
    /* HERE, say that i cant use "==" */
    
            if ((SScory->m_SPlayers[playernumber].m_cName) == (SScory->m_SPlayers[ui].m_cName))
    		
    		{
    			cout<<"blabla";
    		}
    	}
    }
    
  • shwaipshwaip bluffin' with my muffin Icrontian
    edited August 2005
    i believe that using '==' compares the pointers to see if they are equal. you want to use strcmp(str1,str2)
    if(strcmp(SScory->m_SPlayers[playernumber].m_cName, SScory->m_SPlayers[ui].m_cName) == 0)
    

    should do what you want.
  • Yui-IkariYui-Ikari edmonton
    edited August 2005
    YEs, thanks so much <3 ^.^
  • Yui-IkariYui-Ikari edmonton
    edited August 2005
    c:\Documents and Settings\yui\Desktop\c++\252 summer\golfy\Structs.cpp(65): error C2664: 'strcmp' : cannot convert parameter 1 from 'std::string' to 'const char *'
    :(

    c:\Documents and Settings\yui\Desktop\c++\252 summer\golfy\Structs.cpp(75) : error C2676: binary '==' : 'std::string' does not define this operator or a conversion to a type acceptable to the predefined operator
    >_<
  • sharkydartsharkydart KY Icrontian
    edited August 2005
    it's funny that the last time I posted, I answered this exact same question from someone else, and it is like 1 post back in this thread. But, you're new, and I'm bored so here goes.

    The reason you can't use the "==" operator is because String does not define what "==" does with a string. Instead, included with String is ".equals()", which when used will do the same thing that you wanted to do with the "==" operator.

    In your SPlayer struct, you have m_cName as type "stringr" - is that a typo? I know that would give you a different error.

    Also, maybe I am wrong here, but I think you should have "playernumber" either created as a global, or (more likely) in your SScoreCard struct. I won't comment any futher since you're just trying to get string comparison going and probably not worrying about anything else.
  • TheBaronTheBaron Austin, TX
    edited August 2005
    the nicest thing about C and C++ compilers is that when you have something wrong, they will ALWAYS point it out to you and will ALWAYS tell you exactly whatyou need to fix. your error messages told you exactly the same thing that everyone else will tell you, that you cannot use '==' with a string. you should also learn how to use char* instead of strings, it will probably be beneficial to you in the future, just null terminate
  • Yui-IkariYui-Ikari edmonton
    edited August 2005
    sharkydart wrote:
    it's funny that the last time I posted, I answered this exact same question from someone else, and it is like 1 post back in this thread. But, you're new, and I'm bored so here goes.

    The reason you can't use the "==" operator is because String does not define what "==" does with a string. Instead, included with String is ".equals()", which when used will do the same thing that you wanted to do with the "==" operator.

    In your SPlayer struct, you have m_cName as type "stringr" - is that a typo? I know that would give you a different error.

    Also, maybe I am wrong here, but I think you should have "playernumber" either created as a global, or (more likely) in your SScoreCard struct. I won't comment any futher since you're just trying to get string comparison going and probably not worrying about anything else.

    lol thanks ^_^U , i was tired and was late ^_^U
    that "stringr" suposse to be "string"
    I kinda shorted out my program... , instead of copy pasting the whole code, i just left the escencial part ^__^
    Ty
  • sharkydartsharkydart KY Icrontian
    edited August 2005
    TheBaron wrote:
    the nicest thing about C and C++ compilers is that when you have something wrong, they will ALWAYS point it out to you and will ALWAYS tell you exactly whatyou need to fix.

    I really, really, really, really, REALLY wish this was true. Alot better than compiler errors with java (oh wait, usually that doesn't happen and it's just that something is left f'd up and it runs anyway) and web page stuff (any of them where the browser returns a generic error message... I hate that). I'd say that should be a "USUALLY" or "MORE OFTEN THAN MOST" instead of "ALWAYS" - especially in the second instance.
Sign In or Register to comment.