There is a string that needs to be broken down by separator and save the result in the structure. What is the best (fastest in speed) algorithm for this you can use? I would like something like an XML serializer in C #.

Example string:

0,303567,3584,w,0.000000 

Structure:

 struct REQUEST{ unsigned int asu; unsigned int lba; long size; char opcode; double timestamp; REQUEST() { asu = 0; lba = 0; size = 0; opcode = ' '; timestamp = 0; } }; 
  • Your question is not entirely correct. On the one hand, you want a ready-made solution (the algorithm built in the library), and on the other hand, the fastest in speed. It does not happen. The fastest is manually written. Take a string and parse it character by character. It is faster than built-in library functions at times, with straight arms. - Zealint
  • @Zealint, that is, in the old-fashioned way, sort through everything using while, write to a temporary buffer, and then push into a structure? I thought there is a more beautiful way. - neo
  • Yes, but you yourself said that you need a fast algorithm. He will be fast. Any library functions, of course, will be more beautiful (and you have already been given a good answer below), but they are designed for universal cases, therefore there are more checks than anything, etc. They are slower. It seems to me that you hardly want exactly the fastest solution ... I just expressed my opinion on the correctness of the question wording. - Zealint
  • @Zealint, maybe I somehow didn’t put it that way, but in this case I choose speed between beauty and speed , because there will be many such lines, and the faster they get rid of it, the better. Therefore, the speed in this case is paramount. - neo

2 answers 2

It seems that the idiomatic version of C ++ is:

 using namespace std; istream& getrecord(istream& s, REQUEST& req) { string part; bool result = getline(s, part, ',') && (istringstream(part) >> req.asu) && getline(s, part, ',') && (istringstream(part) >> req.lba) && getline(s, part, ',') && (istringstream(part) >> req.size) && getline(s, part, ',') && ((part.size() == 1) ? (req.opcode = part[0], true) : false) && getline(s, part, ',') && (istringstream(part) >> req.timestamp); if (!result && s) s.setstate(ios::failbit); return s; } int main() { string original("0,303567,3584,w,0.000000"); REQUEST req; istringstream origs(original); if (getrecord(origs, req)) cout << "asu = " << req.asu << ", lba = " << req.lba << ", size = " << req.size << ", opcode = " << req.opcode << ", timestamp = " << req.timestamp; else cout << "FAILED"; } 

Unfortunately, stringstream can not read in char , so it turned out not so beautiful.

Check: http://ideone.com/IPtprZ

  • what is this a bunch of &&, kidding? :) - ixSci
  • @ixSci: Well, such a method to control the control flow :) - VladD
  • @ixSci: corrected to send the stream to a fail state on error. - VladD
  • one
    @VladD, found a bug. It is necessary to put brackets for the entire expression in the line where the character is obtained. It should be like this: ((part.size () == 1)? (Req.opcode = part [0], true): false) && - neo
  • one
    @neo: Really? Okay, I'll fix it in the answer :) - VladD

For example, strtok with string conversion to the desired type (and error checking).

The option with the introduction of stringstream and subsequent analysis, perhaps, the effectiveness will be worse.

  • Can you justify: "The option to make it into stringstream with subsequent analysis, perhaps, will be worse in terms of efficiency" ? - neo
  • What is there to justify? The mere transfer to the memory, back and forth, all sorts of overhead, error handling in the streams ... Yes, just write a test program and compare - I am sure in the results :) - Harry