c++ - 如何使用 string::find 从字符串中的字符中找到位置?
问题描述
我需要字符串中字符的位置。字符串包含:
"username":"secret", "password":"also secret", "id":"secret too", "token":"secret"
我需要标记中粗体引号的位置: "token": " secret "。我已经尝试过来自http://www.cplusplus.com/reference/string/string/find的代码, 但一切都没有奏效。谁能帮我?这是我尝试过的,但它只给出0:
#include <iostream>
#include <string>
int main() {
std::string buffer("\"username\":\"secret\", \"password\":\"also secret\", \"id\":\"secret too\", \"token\":\"secret\"");
size_t found = buffer.find('"');
if (found == std::string::npos)std::cout << "something went wrong\n";
if (found != std::string::npos)
std::cout << "first " << '"' << " found at: " << found << '\n';
for (int j = 0; j <= 17; ++j) {
found = buffer.find('"');
found + 1, 6;
if (found != std::string::npos)
std::cout << "second " << '"' << " found at : " << found << '\n';
}
return 0;
解决方案
有很多可能的解决方案。所以,很难回答。
基本上需要做的是,逐个位置地遍历字符串,然后检查字符是否是搜索到的字符,然后对结果做一些事情。
第一个简单的实现可以是:
#include <iostream>
#include <string>
const std::string buffer("\"username\":\"secret\", \"password\":\"also secret\", \"id\":\"secret too\", \"token\":\"secret\"");
int main() {
for (size_t position{}, counter{}; position < buffer.length(); ++position) {
if (buffer[position] == '\"') {
++counter;
std::cout << "Character \" number " << counter << " found at position " << position << '\n';
}
}
return 0;
}
但是,您的问题是关于std::string.find()
. 在您的实现中,您总是在std::string
. 因此,您将始终在位置 0 处找到相同的 "。
解决方案:找到第一个匹配项后,使用结果pos
(加一)作为std::string.find()
函数的第二个参数。然后您将在第一个找到 " 之后开始搜索,从而找到下一个。所有这些都可以在正常的循环中完成for
。
请参阅下面的下一个简单示例:
#include <iostream>
#include <string>
const std::string buffer("\"username\":\"secret\", \"password\":\"also secret\", \"id\":\"secret too\", \"token\":\"secret\"");
int main() {
for (size_t position{}, counter{}; std::string::npos != (position = buffer.find("\"", position)); ++position, ++counter) {
std::cout << "Character \" number " << counter << " found at position " << position << '\n';
}
return 0;
}
还有更多的解决方案,这取决于你真正想做的事情。您可以使用简单的正则表达式提取所有关键字和数据。
像这样的东西:
#include <iostream>
#include <string>
#include <regex>
#include <vector>
const std::regex re{ R"(\"([ a-zA-Z0-9]+)\")" };
const std::string buffer("\"username\":\"secret\", \"password\":\"also secret\", \"id\":\"secret too\", \"token\":\"secret\"");
int main() {
std::vector part(std::sregex_token_iterator(buffer.begin(), buffer.end(), re, 1), {});
std::cout << part[7] << '\n';
return 0;
}
或者,您可以将所有内容拆分为标记和值。像这样:
#include <iostream>
#include <string>
#include <regex>
#include <vector>
#include <map>
#include <iomanip>
const std::regex re1{ "," };
const std::regex re2{ R"(\"([^\"]+)\")" };
const std::string buffer("\"username\":\"secret\", \"password\":\"also secret\", \"id\":\"secret too\", \"token\":\"secret\"");
int main() {
std::vector<std::string> block(std::sregex_token_iterator(buffer.begin(), buffer.end(), re1, -1), {});
std::map<std::string, std::string> entry{};
for (const auto& b : block) {
std::vector blockPart(std::sregex_token_iterator(b.begin(), b.end(), re2, 1), {});
entry[blockPart[0]] = blockPart[1];
}
for (const auto& [token, value] : entry)
std::cout << std::setw(20) << token << " --> " << value << '\n';
return 0;
}
但是如果你有一个复杂的给定格式,比如 JSON,那么有很多特殊情况,唯一有意义的方法就是使用现有的库。
推荐阅读
- python - Python 2 到 3 迁移:AttributeError: 'int' object has no attribute 'replace'
- c++ - 关于向量初始化的一些问题
- c# - 使用 Android videoview 进行 HLS 直播
- php - 如果编辑表单字段为空,如何将数据保留在数据库中
- nlp - 是否有任何工具可以为给定的单词输入提供单独的词根和词缀?
- git - 在 git 中创建 repo 并使用 bitbucket 进行 sincronize
- sockets - 如何检测 AIX 和 Solaris 的 TCP 套接字上是否启用了 keepalive?
- java - 如何从 Scala 中的 JSON 中的键中获取特定值?
- multithreading - 多线程 Kafka Consumer 未并行处理所有分区
- algorithm - 为什么数字以 "12-256" 、 "13-256" 而不是 12,13 等形式打印?