查找字符串中某个字符的所有出现情况
Finding all occurrences of a character in a string
我有逗号分隔的字符串,我需要从中提取值。问题是这些字符串永远不会是固定大小的。因此,我决定遍历逗号组并读取中间的内容。为了做到这一点,我做了一个函数,返回每个事件的位置在一个示例字符串。
这是一个聪明的方法吗?这被认为是糟糕的代码吗?
#include <string>
#include <iostream>
#include <vector>
#include <Windows.h>
using namespace std;
vector<int> findLocation(string sample, char findIt);
int main()
{
string test = "19,,112456.0,a,34656";
char findIt = ',';
vector<int> results = findLocation(test,findIt);
return 0;
}
vector<int> findLocation(string sample, char findIt)
{
vector<int> characterLocations;
for(int i =0; i < sample.size(); i++)
if(sample[i] == findIt)
characterLocations.push_back(sample[i]);
return characterLocations;
}
vector<int> findLocation(string sample, char findIt)
{
vector<int> characterLocations;
for(int i =0; i < sample.size(); i++)
if(sample[i] == findIt)
characterLocations.push_back(sample[i]);
return characterLocations;
}
正如目前所写的,这将简单地返回一个包含字符本身的int表示的向量,而不是它们的位置,这是你真正想要的,如果我没看错你的问题的话。
替换这一行:
characterLocations.push_back(sample[i]);
characterLocations.push_back(i);
这就得到了你想要的向量。
如果我在回顾这个,我会看到这个,并假设你真正想做的是标记一个字符串,已经有很好的方法来做到这一点。
我所见过的最好的方法是使用boost::tokenizer
。它允许您指定字符串的分隔方式,然后为您提供一个很好的迭代器接口来遍历每个值。
using namespace boost;
string sample = "Hello,My,Name,Is,Doug";
escaped_list_seperator<char> sep("" /*escape char*/, ","/*seperator*/, "" /*quotes*/)
tokenizer<escaped_list_seperator<char> > myTokens(sample, sep)
//iterate through the contents
for (tokenizer<escaped_list_seperator<char>>::iterator iter = myTokens.begin();
iter != myTokens.end();
++iter)
{
std::cout << *iter << std::endl;
}
输出:Hello
My
Name
Is
Doug
Edit如果你不想依赖boost,你也可以像这个答案一样使用getline
和istringstream
。从这个答案中复制一些内容:
std::string str = "Hello,My,Name,Is,Doug";
std::istringstream stream(str);
std::string tok1;
while (stream)
{
std::getline(stream, tok1, ',');
std::cout << tok1 << std::endl;
}
输出: Hello
My
Name
Is
Doug
这可能不是直接你要问的问题,但我认为这是你想要解决的整体问题。
对我来说也很好,一个注释是变量和类型的命名。你调用向量,你将返回int
类型的characterLocations
,当你真正推回字符本身(char
类型)而不是它的位置时。我不确定更大的应用程序是什么,但我认为将位置传递回去会更有意义。或者使用更简单的字符串标记。
如果你的目的是找到出现的索引,下面的代码将更有效,因为在c++中,将对象作为参数会导致对象被复制,这是不安全的,而且效率较低。特别是在这种情况下,返回一个向量是最糟糕的做法,这就是为什么把它作为参数引用会好得多。
#include <string>
#include <iostream>
#include <vector>
#include <Windows.h>
using namespace std;
vector<int> findLocation(string sample, char findIt);
int main()
{
string test = "19,,112456.0,a,34656";
char findIt = ',';
vector<int> results;
findLocation(test,findIt, results);
return 0;
}
void findLocation(const string& sample, const char findIt, vector<int>& resultList)
{
const int sz = sample.size();
for(int i =0; i < sz; i++)
{
if(sample[i] == findIt)
{
resultList.push_back(i);
}
}
}
它有多聪明也取决于你如何处理那些用逗号分隔的子字符串。在某些情况下,避免搜索和分割,同时解析和处理字符串可能会更好(例如,更快,内存需求更小),可能使用状态机。
- 在这种情况下,我真的复制了字节还是复制了字符?
- 在不使用字符串库的情况下输入字符*
- 如何在不知道对应关系的情况下在字符串中搜索字符并将其分配给另一个字符?
- 当对字符变量使用toupper()时,所述char变量输出多个字符.我该如何防止这种情况发生
- 如果字符串在 C/C++ 中没有 NUL 字符(以防编译器允许它通过)会发生什么情况?
- 如何在不将其转换为 ASCII 字符的情况下显示 QByteArray 的十六进制值
- 整数指针与字符指针的情况下悬空指针
- 有没有办法在不使用任何迭代的情况下将字符的字母顺序排列
- 除了字符串或宏调用之外,是否存在任何情况,其中"(<"是有效的字符流?
- 如何在没有wchar_t的情况下在 c++ 中解码/编码 UTF-8 字符
- 给定一个填充无符号字符**的 C 函数,如何在没有中间副本的情况下用数据填充 std::vector
- 为什么在指针和数组的情况下,字符数组的处理方式不同
- 切换情况,用户输入,确定其是什么字符
- 是否可以超载[]运算符在不定义类的情况下访问特定的字符
- 如何在不定义目标变量大小的情况下逐个字符将字符串变量复制到另一个字符
- 如何在不使用循环的情况下将低字节和高字节的字符数组转换为它们的整数数组
- C++ 在不使用 C 字符串库函数的情况下替换数组中的字符
- 我可以在不复制的情况下将 std::vector 重新解释<char>为 std::vector<无符号字符>吗?
- C 计数字符来自文本文件,无论情况如何
- 如何在不删除任何字符的情况下将字符从字符串中的某个位置移动到其最前面