I'm trying to parse a text file to find a pattern then grab a substring. This code fragment works fine, however can I improve this? Can I minimize copying here? I.e. I get a line and store it in the buf then construct a string, can this copying be eliminated?
In short what's the idiomatic way of achieving this?
std::ifstream f("/file/on/disk");
while (!f.eof()) {
char buf[256];
f.getline(buf, sizeof(buf));
开发者_开发百科 std::string str(buf);
if (str.find(pattern) != std::string::npos)
{
// further processing, then break out of the while loop and return.
}
}
Here's one possible rewrite:
std::ifstream f("/file/on/disk");
char buffer[256];
while (f.getline(buffer, sizeof(buf))) { // Use the read operation as the test in the loop.
if (strstr(buffer, pattern) != NULL) { // Don't cast to string; costs time
// further processing, then break out of the while loop and return.
}
}
The main changes are marked inline, but to summarize:
- Use the read operation as the test in the while loop. This makes the code a lot shorter and clearer.
- Don't cast the C-style string to a
std::string
; just usestrstr
to do the scan.
As a further note, you probably don't want to use a C-style string here unless you're sure that's what you want. A C++ string
is probably better:
std::ifstream f("/file/on/disk");
std::string buffer;
while (std::getline(f, buffer)) { // Use the read operation as the test in the loop.
if (buffer.find(pattern) != std::string::npos) {
// further processing, then break out of the while loop and return.
}
}
In your code, you first copy characters from the file into a char
array. That should be all the copying necessary. If you'd need to read each character once then even that copy wouldn't be necessary.
Next, you construct a std::string
from the array you filled. Again, unnecessary. If you want a string then copy from the stream directly into a string.
std::ifstream f("/file/on/disk");
for( std::string line; std::getline(f, line); ) {
if (str.find(pattern) != std::string::npos) {
// further processing, then break out of the while loop and return.
}
}
You don't need that char[]
at all.
string line;
std::getline(f, line);
if (line.find(pattern) != std::string::npos)
{
....
}
精彩评论