Thread: Bizarre behavior of the string::find() function

  1. #1
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827

    Bizarre behavior of the string::find() function

    I have the following function:

    Code:
    string C_replace_operations::generateNewFileStr(const vector<string>& searchStrs, const vector<string>& replaceStrs) {
    
        string new_file_str;
        string buffer_str;
    
        if (searchStrs.size() != replaceStrs.size()) {
           cerr<< "Error! You must pass the same number of searchStrs as replaceStrs!\n"
                  "You passed " << searchStrs.size() << " searchStrs, but you passed " <<
                  replaceStrs.size() << " replaceStrs.\n\n";
           return new_file_str; //an empty string, since there must be the same number of search strings as there are replace strings,
           //though there can be empty replace strings
        }
    
        if (vectorOnlyContainsEmptyStrings(searchStrs)) {
           cerr<< "Error! You must pass at least one non-empty search string!\n"
                  "Duh!\n";
           return new_file_str; //an empty string
        }
    
        if (vectorOnlyContainsEmptyStrings(replaceStrs)) {
           cerr<< "Error! You must pass at least one non-empty replace string!\n"
                  "Duh!\n";
           return new_file_str;
        }
    
        bool found_all_search_strs_in_current_line = true; //in faith...haha
        size_t find_result = 0;
        while (!input_filestream.eof()) {
              getline(input_filestream, buffer_str);
              //cout<< "Just read a line." <<endl;
              //cout<< "buffer_str is: " << buffer_str <<endl;
              if (input_filestream.good()) {
                 for (size_t i = 0; i < searchStrs.size(); i++) {
                     find_result = buffer_str.find(searchStrs.at(i), 0);
                     if (find_result == string::npos) { //meaning the current searchStr was not found in current line
                        cout<< "find_result == string::npos" <<endl;
                        //cin.get();
                        found_all_search_strs_in_current_line = false;
                        break; //since all searchStrs must be contained within the current line to be counted
                     }
                     else
                        cout<< "find_result is: " << find_result <<endl;
                 }
    
                 if (found_all_search_strs_in_current_line) {
                    //cout<< "All search strings were found in current line." <<endl;
                    //cout<< "buffer_str before replacing part of the content is:\n\n" << buffer_str << '\n' <<endl;
                    //cout<< "Press Enter to continue.\n" <<endl;
                    //cin.get();
                    for (size_t i = 0; i < searchStrs.size(); i++) {
                        find_result = buffer_str.find(searchStrs.at(i), 0);
                        if (!replaceStrs.at(i).empty()) {
                           cout<< "searchStrs.at(" << i << ") is:\n\n" << searchStrs.at(i) <<endl;
                           cout<< "replaceStrs.at(" << i << ") is:\n\n" << replaceStrs.at(i) <<endl;
                           cout<< "find_result is: " << find_result <<endl;
                           buffer_str.replace(find_result, searchStrs.at(i).size(), replaceStrs.at(i));
                           replaced_strs = true;
                           //cout<< "Just replaced the string in buffer_str that matches the string\n"
                           //       "searchStrs.at(" << i << ").\n" <<endl;
                           //cout<< "Press Enter to continue.\n" <<endl;
                           //cin.get();
                           //cout<< "searchStrs.at(" << i << ") is the following quoted string, without\n"
                           //       "the quotes:\n\n\"" << searchStrs.at(i) << "\"\n" <<endl;
                           //cout<< "Press Enter to continue.\n" <<endl;
                           //cin.get();
                           //cout<< "The string that replaced the above quoted string is the following\n"
                           //       "quoted string:\n\n\"" << replaceStrs.at(i) << "\"\n" <<endl;
                           //cout<< "Press Enter to continue.\n" <<endl;
                           //cin.get();
                        }
                    }
                 }
    
                 else
                     found_all_search_strs_in_current_line = true; //reset to true - in faith, haha
    
                 new_file_str += buffer_str; //add the current line, modified or not, to the new file's content string
                 new_file_str += '\n';
              }
        }
    
        return new_file_str;
    
    }
    Its supposed to replace certain content of a string read from line which contains all search strings. Basically, each search string in the line which contains is supposed to be replaced by the string at the same index. Search strings and replace strings are each stored inside a vector<string>.

    This function has worked ok up until today, after which I'm getting weird unexpected results. Basically, the string::find() function is returning string::npos when its not supposed to (i.e. when each search string IS contained inside buffer_str), thereby causing an instance of 'std:ut_of_range' to be thrown from string::replace().

    Please take a look at the above code, and see if you can spot any above errors. I've already been through the code several times, but have not seen why it should be doing this. Note that I call the above function only once too.

    See attachment for output. The .txt at the end will need to removed to view the PNG image.

    Thanks.
    Last edited by Programmer_P; 03-08-2011 at 09:18 PM.
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Sorry, but I'm not interested in going through the process of renaming txt to png files.

    If you want help, post a sample of relevant code (i.e. something small and complete that, when compiled and linked, consistently recreates the problem), describe the output you expect, and describe the output you get.

    The most likely reason is that you have some other code that is molesting a pointer, so it is tromping on memory used by one or more of your strings. A symptom of that would be, if you try to strip down to a small actually-illustrative code sample, that the problem will go away when you snip some apparently unrelated code.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    I don't see anywhere in that code or your output where find() is returning something other than npos when the search string cannot be found. The bug is elsewhere in your code.

    I also cannot fathom why you would post a screenshot of your code instead of the actual code. Is copy/paste broken on your operating system?
    bit∙hub [bit-huhb] n. A source and destination for information.

  4. #4
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by bithub View Post
    I don't see anywhere in that code or your output where find() is returning something other than npos when the search string cannot be found. The bug is elsewhere in your code.
    My bad. Please see edit.
    I also cannot fathom why you would post a screenshot of your code instead of the actual code. Is copy/paste broken on your operating system?
    I posted a screenshot of my program output, not my code (and that because I could not copy/paste the output from the xterm program window). lol...
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You should know that using eof() as loop control is bad. There's even a faq on the site about it. Use the getline as loop control.
    And then you are doing Microsoft-style by checking if it succeeds and wrapping the rest of the code in one big block instead of just checking if it failed and cleaning up.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Programming King Mr.777's Avatar
    Join Date
    Mar 2011
    Location
    Middle of NoWhere
    Posts
    320
    Quote Originally Posted by Elysia View Post
    You should know that using eof() as loop control is bad. There's even a faq on the site about it. Use the getline as loop control.
    And then you are doing Microsoft-style by checking if it succeeds and wrapping the rest of the code in one big block instead of just checking if it failed and cleaning up.
    I don't think, if eof() using in loop is that bad....
    I always keep using this when i play with files.....
    Can you kindly give me a reason for this??? May be i am wrong...

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Programming King Mr.777's Avatar
    Join Date
    Mar 2011
    Location
    Middle of NoWhere
    Posts
    320
    @Elysia: There is the difference between EOF() and FEOF().... Must read..... :-)

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    In the end, they do the same thing.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    If you read as much as you recommend then you would know that feof() and stream.eof() work the same, despite being named slightly differently. Besides, reaching end of file is only the best reason to exit the loop; it doesn't cover things like read errors, that may need to break the loop early.

  11. #11
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by Elysia View Post
    You should know that using eof() as loop control is bad. There's even a faq on the site about it. Use the getline as loop control.
    And then you are doing Microsoft-style by checking if it succeeds and wrapping the rest of the code in one big block instead of just checking if it failed and cleaning up.
    Quote Originally Posted by whiteflags View Post
    If you read as much as you recommend then you would know that feof() and stream.eof() work the same, despite being named slightly differently. Besides, reaching end of file is only the best reason to exit the loop; it doesn't cover things like read errors, that may need to break the loop early.
    Well, that's why I check to make sure that input_filestream.good() returns true before attempting to do anything with buffer_str, so I don't see why this a problem. I also don't know how I would use getline instead to control the loop. Can you please show an example of this working? Thanks.

    As for the "Microsoft-style" thing, I don't see a problem with that logic either (i.e. checking if it succeeded, instead of checking if it failed). Feel free to argue that point though.
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You do
    while ( getline(...) )
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by Elysia View Post
    You do
    while ( getline(...) )
    But getline returns an istream&, not a bool or integer.
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Programmer_P
    But getline returns an istream&, not a bool or integer.
    An istream is convertible to bool through the void* conversion function.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Programming Ninja In-T...
    Join Date
    May 2009
    Posts
    827
    Quote Originally Posted by laserlight View Post
    An istream is convertible to bool through the void* conversion function.
    What void* conversion function?
    I'm an alien from another world. Planet Earth is only my vacation home, and I'm not liking it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling C in Visual Studio 2005
    By emanresu in forum C Programming
    Replies: 3
    Last Post: 11-16-2009, 04:25 AM
  2. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  3. Troubleshooting Input Function
    By SiliconHobo in forum C Programming
    Replies: 14
    Last Post: 12-05-2007, 07:18 AM
  4. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  5. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM