问题描述
我正在研究一个需要两次用户输入的程序。用户将输入一个句子,然后输入关键字,以删除整个句子中找到的每个匹配项,并返回剩余内容。我下面的“逻辑”代码是...
char delim[AFFIX];
strcpy(delim,userInput); //storing the phrase user wants to remove
char *token = strtok(sentence,delim);
while (token)
{
cout << token << endl;
token = strtok(NULL,delim);
}
我遇到的问题是strtok会删除找到的字符的每个单个实例。例如,如果用户希望删除“ pre”的所有实例,则单词“ preformed”将变为“ fom d”而不是formed。有没有一种方法可以限制strtok删除找到的每个字符实例,而只删除一系列字符?
我知道使用字符串或向量会使我的生活变得更轻松,但是我想使用字符数组。如果这还不够清楚,我真的很抱歉,我对C ++很陌生。任何有关如何解决此问题的建议将不胜感激。谢谢您的时间。
解决方法
一个简单的或多或少肮脏的解决方案是仅在搜索词前后添加空格。为了确保它实际上是一个完整的单词而不是单词的一部分。
例如:
- 输入:“ pre”
- 检查:“ pre”
为确保您也剪切了第一个单词,如果第一个单词也是输入的单词,则需要检查字符串的第一部分并在其前面添加一个空格。
示例:
#include <string>
#include <iostream>
void removeSubstrs(std::string& s,std::string& p) {
std::string::size_type n = p.length();
for (std::string::size_type i = s.find(p);
i != std::string::npos;
i = s.find(p))
s.erase(i,n);
}
void check(std::string& s,std::string& p) {
int slen = s.length();
int plen = p.length();
std::string firstpart = s.substr (0,plen);
std::string lastpart = s.substr (slen-plen,slen);
if (firstpart == p) {
s = " " + s;
}
if (lastpart == p) {
s += " ";
}
}
int main ()
{
std::string str = "pre test inppre test pre";
std::string search = "pre";
std::string pattern = " " + search + " ";
check(str,search);
removeSubstrs(str,pattern);
std::cout << str << std::endl;
return 0;
}
,
strtok在这里不是正确的选择,您可以将strtok的第二个参数视为一个定界符列表(该列表中的每个char都是一个定界符),并使用这些定界符将字符串分解为标记。 更好的解决方案是采用strstr和strcat。 也许像这样(使用MSVC ++)
void removeSubstr(char *string,const char *sub,int n) {
char *match;
int len = strlen(sub);
while ((match = strstr(string,sub))) {
*match = '\0';
strcat_s(string,n,match + len);
}
}
int main() {
char test[] = "abcxyz123xyz";
removeSubstr(test,"xyz",sizeof(test) / sizeof(char));
cout << test << endl;
}
strcat_s是strcat的更安全版本(MSVC ++比strcat更加喜欢它:p) 有更好的方法可以执行此操作,但我会根据您的要求将自己限制为char数组...