Function of mine isn't taking strings right.

This is a discussion on Function of mine isn't taking strings right. within the C++ Programming forums, part of the General Programming Boards category; Basically, it takes a vector, a string, and a few other optional parameters. It then searches through the vector till ...

  1. #1
    Registered User
    Join Date
    Jan 2005
    Posts
    106

    Function of mine isn't taking strings right.

    Basically, it takes a vector, a string, and a few other optional parameters. It then searches through the vector till it find the string, and returns the index.

    Code:
    size_t get_index(vector<string>to_search, string search_str, size_t start=0, int error_number=0, string error_msg = "was not found!")
    {
      size_t x=start;
      if(error_number = 0)
      {
        error_number = to_search.size();
      }
      if(to_search.empty())
      {
        cout << search_str << " " << error_msg << "\n";
        return error_number;
      }  
      while(to_search[x] != search_str)
      {
        if(x == (to_search.size()-1))
        {
          cout << search_str << " " << error_msg << "\n";
          return 0;
        }
        x++;
      }  
      return x;
    }
    Problem? It works normally if I call it with x=get_index(search_vec,"search"), but if I pass in a string-type VARIABLE (string search="seach; get_index(seach_vec,search)), it can't find the string.

    What's odd is that I don't recall it doing this before, so I'm not really sure what's changed.

    Also, I've checked. It's not like it's not READING the strings, becuase I had to_search[x] be printed at each step of the while. It's just... not getting that they're equivalent.

  2. #2
    Rabite SirCrono6's Avatar
    Join Date
    Nov 2003
    Location
    California, US
    Posts
    269
    It compiles and works fine for me. I've tried variable and static, both with and without changing "error_number = 0" to "error_number == 0", both with strings that don't exist and strings that do.
    Code:
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    size_t get_index( vector<string> to_search, string search_str, size_t start = 0, int error_number = 0, string error_msg = "was not found!" )
    {
      size_t x = start;
      if( error_number == 0 )
      {
        error_number = to_search.size();
      }
      if( to_search.empty() )
      {
        cout << search_str << " " << error_msg << "\n";
        return error_number;
      }  
      while( to_search[x] != search_str )
      {
        if( x == ( to_search.size() - 1 ) )
        {
          cout << search_str << " " << error_msg << "\n";
          return 0;
        }
        x++;
      }  
      return x;
    }
    
    int main( void )
    {
      std::vector<std::string> TestVector;
      TestVector.push_back( "Element0" );
      TestVector.push_back( "Element1" );
      std::string TestString = "Element1";
      int x = get_index( TestVector, TestString );
      std::cout << x;
      std::cin.get();
      return 0;
    }
    Output: 1. This was my last test. Also I'm going to assume those bottom things were random typos.
    From C to shining C++!

    Great graphics, sounds, algorithms, AI, pathfinding, visual effects, cutscenes, etc., etc. do NOT make a good game.
    - Bubba

    IDE and Compiler - Code::Blocks with MinGW
    Operating System - Windows XP Professional x64 Edition

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    106
    Yeah, it works elsewhere for me. I thought it wasn't at first, but further tests show that it *does*. Anyway, this is the function that's calling it and acting funny.

    Code:
    void execute(vector<string>commands, vector<string>params, int start, int stop=0)
    {
      string f[4] = {"end","makevar","print","set_current"};
      vector<string>instr(f,f+4);
      vector<string>tok_par;
      int x = start+1;
      int y = 0;
      while(params[x] != "stop")
      {
        tok_par = tokenize(params[x]);
        y=get_index(instr,commands[x]);
        incode[y](tok_par);
        x++;
      }
    }
    Keep in mind that here, the target word is "print." I'm assuming I've got a flaw in how the instr vector is initalized. However, couting random members from it seems to work and, as I said, it still takes raw strings that aren't stored in a container.

    incode, btw, is just a function pointer array.

  4. #4
    Rabite SirCrono6's Avatar
    Join Date
    Nov 2003
    Location
    California, US
    Posts
    269
    Script interpreter of some kind?

    vector<string>instr(f,f+4);
    I believe this would be the equivilant of f[0], f[4]. f[4] is out of bounds isn't it? Or does f+4 come out as f[3]?
    From C to shining C++!

    Great graphics, sounds, algorithms, AI, pathfinding, visual effects, cutscenes, etc., etc. do NOT make a good game.
    - Bubba

    IDE and Compiler - Code::Blocks with MinGW
    Operating System - Windows XP Professional x64 Edition

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    106
    No, that's in-bounds. I think the 4 is just the number of elements to copy over. I don't think THAT'S a problem.

    Also, it's actually working really well so far except for this

  6. #6
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    Quote Originally Posted by SirCrono6
    Script interpreter of some kind?

    vector<string>instr(f,f+4);
    I believe this would be the equivilant of f[0], f[4]. f[4] is out of bounds isn't it? Or does f+4 come out as f[3]?
    No, that's in-bounds.
    No, it's not inbounds. f is a pointer to the first element, so f+4 is one past the end. However, one past the end is the proper address. By definition, the range does not include what's at the last address. All the STL containers employ pointers that point to one past the end.

    I'm assuming I've got a flaw in how the instr vector is initalized.
    No. Vectors have a constructor which accepts a range of values, which is what you are using, and in any case that can be easily checked:
    Code:
    string f[4] = {"end","makevar","print","set_current"};
    vector<string> instr(f,f+4);
    
    for(vector<string>::iterator pos = instr.begin(); pos != instr.end(); ++pos)
    {
    	cout<<*pos<<endl;
    }
    Last edited by 7stud; 01-29-2006 at 09:15 PM.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    106
    No, it's not inbounds.
    Right, right. I know. I mean it wasn't, like, the sort of not inbounds that causes segfaulting.

    Anyway, that bit aside, I also tried just searching the vector. Same problems. amusingly enough, it CAN take string containers. However, it CANNOT take string containers stored in the commands vector.

    This is really odd because if I set a string to something in the commands vector and pass THAT string, it... like, still has the same problem.
    Last edited by suzakugaiden; 01-29-2006 at 10:02 PM.

  8. #8
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    Write up a brief, but complete, example program demonstrating your problem and post it.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,339
    Make sure your spelling is correct (in your original post you misspelled search as seach in the code that isn't working). Also don't forget to #include <string> since you are using the string class. Beyond that, you can use a debugger to step through the code to see why it is not matching.

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    106
    7stud: A brief example program? Okay.

    Code:
    load_script(verb_coms, verb_pars, "data/verbs.txt");
    execute(verb_coms, verb_pars, 0);
    Imagine that. In main(). Now, erm, the code for load_script!

    Code:
    int load_script(vector<string>&to_commands, vector<string>&to_params, string filename, char br1 = '(', char br2 = ')', char br3 = '^')
    {
      ifstream scriptfile(filename.c_str(), ios::in);
      if(!scriptfile)
      {
        cout << "File not found!\n";
        return 0;
      }
      string read;
      int z =0;
      while(read != "#")
      {   
        getline(scriptfile, read, br1); 
        to_commands.push_back(read);
        getline(scriptfile, read, br2);
        to_params.push_back(read);
        getline(scriptfile, read, br3);
        z++;
      }
      return 0;
    }
    Okay. Yeah. I've basically posted all of the relevant code that SHOULD produce a complete working example. Also, here's the complete output of "verbs.txt".

    Code:
    <(look)^
    print(|O desc)^ 
    >(stop)^
    
    <(n)^
    set_current(|O dirN There's no room in that direction. __ cret ||)^
    print(|O desc)^ 
    >(stop)^
    
    <(s)^
    set_current(|O dirS There's no room in that direction. __ cret ||)^
    print(|O desc)^
    >(stop)^
    
    <(e)^
    set_current(|O dirE There's no room in that direction. __ cret ||)^
    print(|O desc)^ 
    >(stop)^
    
    <(w)^
    set_current(|O dirW There's no room in that direction. __ cret ||)^
    print(|O desc)^
    >(stop)^
    
    #(#)#^
    The weird looking crap is escape sequences. I know that works okay, even if it looks a bit wonky. Also, as I said, I'm pretty sure that the resultant input is okay.

    Also, just tested it, but setting the start position for the execute call to 3, so that it starts out with the set_current command, also claims that it can't find it in the vector. KEep in mind that, in the actually execute function, though, if I change "commands[x]" to ""set_current"", it WILL find the search string.

    ---edit---

    Also, at present, a lot of vectors are global. verb_pars and verb_coms in particular. Just to clear that up. I'll probably tie them down to a class later.
    Last edited by suzakugaiden; 01-30-2006 at 01:54 PM.

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,339
    That isn't enough to compile and run. There is no tokenize code. Post the complete example. Compile it yourself and run it to make sure it exhibits the behavior, then post the entire contents of the file all at once.

  12. #12
    Tropical Coder Darryl's Avatar
    Join Date
    Mar 2005
    Location
    Cayman Islands
    Posts
    503
    Okay. Yeah. I've basically posted all of the relevant code that SHOULD produce a complete working example. Also, here's the complete output of "verbs.txt".
    Not quite, because I have no idea where "commands[x]" come from on this line: y=get_index(instr,commands[x]);

    Try putting together an example program in one post that demonstrates the problem. We shouldn't have to piece it together from this and that posting.

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    106
    Darryl: That's from the function parameters.

    Code:
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    string f[4] = {"end","makevar","print","set_current"};
    vector<string>instr(f,f+4);
    
    string current_room;
    vector<string>rooms;
    vector<string>verb_coms;
    vector<string>verb_pars;
    
    //void (*incode[4])(vector<string>) = {&end, &makevar, &print, &set_current};
    
    size_t get_index(vector<string>to_search, string search_str, size_t start=0, int error_number=0, string error_msg = "was not found!")
    {
      size_t x=start;
      if(error_number = 0)
      {
        error_number = to_search.size();
      }
      if(to_search.empty())
      {
        cout << search_str << " " << error_msg << "\n";
        return error_number;
      }  
      while(to_search[x] != search_str)
      {
        if(x == (to_search.size()-1))
        {
          cout << search_str << " " << error_msg << "\n";
          return 0;
        }
        x++;
      }  
      return x;
    }
    
    vector<string>tokenize(string to_tokenize, string delim=" ")
    {
      size_t x=0;
      string check;
      vector<string>tokens;
      while(to_tokenize != "")
      {
        x=strcspn(to_tokenize.c_str(), delim.c_str()); 
        check = to_tokenize.substr(0,x);
        if(check != "")
        {
          tokens.push_back(to_tokenize.substr(0, x));       
        }
        x++;
        to_tokenize.erase(0, x);      
      }
      return tokens;
    }
    
    int load_script(vector<string>&to_commands, vector<string>&to_params, string filename, char br1 = '(', char br2 = ')', char br3 = '^')
    {
      ifstream scriptfile(filename.c_str(), ios::in);
      if(!scriptfile)
      {
        cout << "File not found!\n";
        return 0;
      }
      string read;
      int z =0;
      while(read != "#")
      {   
        getline(scriptfile, read, br1); 
        to_commands.push_back(read);
        getline(scriptfile, read, br2);
        to_params.push_back(read);
        getline(scriptfile, read, br3);
        z++;
      }
      return 0;
    }
    
    void execute(vector<string>commands, vector<string>params, int start, int stop=0)
    {
      
      vector<string>tok_par;
      int x = start+1;
      int y = 0;
      string test = commands[x];
      while(params[x] != "stop")
      {
        tok_par = tokenize(params[x]);
        y=get_index(instr,test);
        //incode[y](tok_par);
        x++;
      }
    }
    
    int main(int argc, char *argv[])
    {
        load_script(verb_coms, verb_pars, "data/verbs.txt");    
        execute(verb_coms, verb_pars, 0);  //Last variable is the start pos. The parser retrieves this.
        //parser();
        system("PAUSE");
        return EXIT_SUCCESS;
    }

  14. #14
    Registered User
    Join Date
    Jan 2005
    Posts
    7,339
    There are newlines in your input file that you aren't handling. You are trying to match "print" against "\nprint".

    I removed the newlines in the commands and it found "print" just fine.

  15. #15
    Rabite SirCrono6's Avatar
    Join Date
    Nov 2003
    Location
    California, US
    Posts
    269
    I tried to write (well, did write I suppose) a simple script interpreter a few days before you asked this (what a coincidence), and I ran into just that problem. Took me about an hour to figure it out.
    From C to shining C++!

    Great graphics, sounds, algorithms, AI, pathfinding, visual effects, cutscenes, etc., etc. do NOT make a good game.
    - Bubba

    IDE and Compiler - Code::Blocks with MinGW
    Operating System - Windows XP Professional x64 Edition

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 02:07 AM
  2. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  3. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  4. Replies: 5
    Last Post: 02-08-2003, 06:42 PM
  5. qt help
    By Unregistered in forum Linux Programming
    Replies: 1
    Last Post: 04-20-2002, 09:51 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21