我是C ++的初学者,所以请理解......
我想通过分别读取每一行,然后在该行中搜索针来搜索文件(haystack)中的字符串(针)。然而,理想情况下,对于更健壮的代码,我希望能够只读取该行上的单个单词,这样如果在单词之间存在较大(即多个)的空白间隙,则在搜索针时会忽略它们。 (例如,可能使用>>运算符??)也就是说,针字符串不必与文件中单词之间的空格大小完全匹配。
所以,例如,如果我有针:
"The quick brown fox jumps over the lazy dog"
文件中的可能会写在(在特定行上):
... "The quick brown fox jumps over the lazy dog" ...
有一种有效的方法吗?
目前我在针线中包含了必要数量的空格,但如果可能的话,我想改进代码。
我的代码目前看起来类似于以下内容(在类中的方法中):
double var1, var2;
char skip[5];
std::fstream haystack ("filename");
std::string needle = "This is a string, and var1 =";
std::string line;
int pos;
bool found = false;
// Search for needle
while ( !found && getline (haystack,line) ) {
pos = line.find(needle); // find position of needle in current line
if (pos != std::string::npos) { // current line contains needle
std::stringstream lineStream(line);
lineStream.seekg (pos + needle.length());
lineStream >> var1;
lineStream >> skip;
lineStream >> var2;
found = true;
}
}
(为了清楚起见,在找到字符串(针)之后,我想在该行上存储下一个单词,或者在某些情况下存储下一个单词,然后跳过一个单词并存储下一个单词,例如:
使用文件:
... ...
... This is a string, and var1 = 111 and 777 ...
... ...
我想提取var1 = 111; var2 = 777;
)
提前感谢您的帮助!
答案 0 :(得分:1)
您可以在line
字符串中找到所有空格字符序列,并将其替换为单个空格。通过这种方式,您也可以替换needle
中的多个空格,其余的搜索算法将继续保持不变。
以下是使用STL删除重复项的方法:
#include <iostream>
#include <algorithm>
#include <string>
#include <iterator>
using namespace std;
struct DupSpaceDetector {
bool wasSpace;
DupSpaceDetector() : wasSpace(0) {}
bool operator()(int c) {
if (c == ' ') {
if (wasSpace) {
return 1;
} else {
wasSpace = 1;
return 0;
}
} else {
wasSpace = 0;
return 0;
}
}
};
int main() {
string source("The quick brown fox jumps over the lazy dog");
string destination;
DupSpaceDetector detector;
remove_copy_if(
source.begin()
, source.end()
, back_inserter(destination)
, detector
);
cerr << destination << endl;
return 0;
}
答案 1 :(得分:1)
虽然我认为有一个更短的解决方案,但这将有效:
std::size_t myfind(std::string ins, std::string str) {
for(std::string::iterator it = ins.begin(), mi = str.begin(); it != ins.end(); ++it) {
if(*it == *mi) {
++mi;
if (mi == str.end())
return std::distance(ins.begin(),it);
}
else {
if(*it == ' ')
continue;
mi = str.begin();
}
}
return std::string::npos;
}
// use:
myfind("foo The quick brown fox jumps over the lazy dog bar", "The quick brown fox");
答案 2 :(得分:0)
要解决您的问题,您应该从针头和干草堆线上剥去多余的空间。 std::unique
被定义为执行此操作。通常在对范围进行排序后使用它,但在这种情况下,我们真正想要做的就是删除重复的空格。
struct dup_space
{
bool operator()( char lhs, char rhs )
{
return std::isspace( lhs ) && std::isspace( rhs );
}
};
void despacer( const std::string& in, std::string& out )
{
out.reserve( in.size() );
std::unique_copy( in.begin(), in.end(),
std::back_insert_iterator( out ),
dup_space()
);
}
您应该像这样使用它:
void find( const std::string& needle, std::istream haystack )
{
std::string real_needle;
despacer( needle, real_needle );
std::string line;
std::string real_line;
while( haystack.good() )
{
line.clear();
std::getline( haystack, line );
real_line.clear();
despacer( line, real_line );
auto ret = real_line.find( real_needle );
if( ret != std::string::npos )
{
// found it
// do something creative
}
}
}