3

I have a function that parses a .csv file and tokenizes each line using a "," as the delimiter. I tokenize it into a vector. I then iterate over that vector and convert each string to a number using a template function. For some reason this works great in all but once compile configuration. I do not know the details of the configrations as they are set up by a different department. I'm hoping you guys see something glaringly wrong with what I've done here and can solve this.

Here is the iteration in question:

vector<std::string> tokens;
tokens = string_split(line);
std::vector<std::string>::iterator it;

for(it = tokens.begin(); it != tokens.end(); it++) {
    int i = 0;
    from_string<int>(i,*it,std::dec);
    if(i != SYS_ELEC_BATTERY_VERSION) {
        SysLoggerMessage("Battery Data does not match this version of the battery model!", MESSAGE_TYPE_ERROR);
        return;
    }
}

So at the point just before the the from_string call, *it is "3". However, when I step into the from_string function:

template <class T>
bool from_string(T& t, const std::string& s, std::ios_base& (*f)(std::ios_base&))
{
      std::istringstream iss(s);
      return !(iss >> f >> t).fail();
}

When stepping into the from_string, s is a BadPtr. Why this works with no problem in some configurations and not in one, I do not know. Any ideas?

Update: I should also mention, for whatever reason, this "Release" configuration does contain debug information so I am able to step into these functions. In from_string, the variable s is showing as this in the debugger:

"<Bad Ptr>" const std::basic_string<char, std::char_traits<char>,std::allocator<char>> &

Update Again The string_split function

vector<string> string_split(const string &source, const char *delimiter, bool keepEmpty) {
      vector<string> results;
      size_t prev = 0;
      size_t next = 0;

      while((next = source.find_first_of(delimiter, prev)) != string::npos)
      {
            if(keepEmpty || (next - prev != 0)) {
                  results.push_back(source.substr(prev,next-prev));
            }
            prev = next + 1;
      }
      if(prev < source.size())
      {
            results.push_back(source.substr(prev));
      }
      return results;
}

Thanks in advance!

4

1 回答 1

1

So I managed to "solve" this finally. I am using Visual Studio 2005 and after talking to another dev in the company we came to this conclusion. For whatever reason, VS2005 doesn't always compile libraries with containers properly. He had ran into a very similar issue on an unrelated project. Here is what "solved" it.

vector<std::string> tokens;
tokens = string_split(line);
std::vector<std::string>::iterator it;

for(size_t index = 0; index < tokens.size(); ++index) {
    int i = 0;
    from_string<int>(i,tokens[index],std::dec);
    if(i != SYS_ELEC_BATTERY_VERSION) {
        SysLoggerMessage("Battery Data does not match this version of the battery model!", MESSAGE_TYPE_ERROR);
        return;
    }
}

Note that the only thing that was changed is the way I am iterating over the vector. Instead of using a std::vector::iterator, im simply using a size_t to index the vector. This works perfectly fine now. I am at a total loss as to what the compiler is doing to break it in one particular configuration.

Thanks to all who read and gave suggestions.

UPDATE

Found the actual problem. The Win32 Release configuration was missing the following pre-processor definition: _SECURE_SCL=0

Apparently this was causing our larger application environment to not properly catch stl container exceptions that are always thrown when they are empty. I don't pretend to fully understand this as I do not have access to the wider environment architecture code but adding that line to the Preprocessor definitions solved the problem without having to change the iterator to an indexed array.

于 2013-06-18T21:18:00.237 回答