[英]Store semicolon-separated integers into array after reading from file
我的数据来自一个如下所示的文本文件:
...
[timestamp]
1096757
[logtime]
2019-10-22 15:29:17.435
[scan]
32;39;36;39;39;39;39;42;42;44;46;48;48;49;51;52;54;54;54;53;50;50;50;54;54;56;56;56;56;57;57;56;56;58;56;56;57;58;58;59;58;59;60;61;60;61;61;60;60;61;61;62;63;63;63;63;63;61;61;61;61;61;61;62;62;62;62;62;62;64;68;64;64;63;61;61;61;60;61;60;62;60;60;59;60;59;59;57;62;57;57;57;57;57;58;63;63;63;63;63;61;61;62;59;59;61;62;61;63;64;63;61;63;61;61;61;63;63;63;59;62;62;59;60;60;60;57;60;61;61;61;61;61;61;56;56;56;57;59;61;61;59;57;57;57;57;59;61;59;61;60;60;60;63;63;63;63;63;63;61;61;61;62;62;62;62;65;69;69;68;68;70;68;72;72;72;71;72;72;73;72;73;73;73;73;73;73;73;73;72;71;69;69;69;69;70;73;70;68;68;68;66;65;66;66;64;64;64;62;60;57;57;57;53;53;53;51;50;47;46;45;44;44;44;44;43;42;43;43;44;45;45;45;45;
[timestamp]
1096858
[logtime]
2019-10-22 15:29:17.532
[scan]
41;38;38;38;38;38;40;40;41;42;46;47;49;49;48;49;50;49;51;52;52;52;52;53;53;53;57;58;58;58;58;57;57;57;56;56;59;56;57;58;58;58;58;58;61;63;59;60;61;60;60;61;61;61;61;61;61;62;62;60;60;60;60;60;60;61;61;61;62;63;63;62;62;62;62;64;65;65;64;59;59;59;60;60;61;61;60;63;63;62;59;58;58;58;59;61;61;62;64;64;64;63;63;60;60;63;64;64;64;63;63;60;58;58;58;59;59;59;59;59;59;59;61;60;60;60;60;60;60;60;60;61;61;59;59;58;58;59;62;62;62;59;59;59;59;59;61;61;61;61;61;60;60;62;62;62;62;62;62;62;62;64;64;66;66;69;69;70;69;69;70;71;71;72;72;72;72;72;73;74;74;71;71;71;70;71;71;71;71;72;72;76;72;71;70;71;70;71;70;66;65;65;64;63;64;60;60;60;
[timestamp]
...
我试图在单词[scan]
之后从数据中获取前 10 个数字。 我设法让我的代码找到数据的行号,但我找不到将数据(每次扫描的前 10 个)放入 int 数组的方法。
我使用了一些我找到的代码,但它并没有像我预期的那样工作。
我正在尝试将数据保存为如下所示。 第一个数组包含:
32
39
36
39
39
39
39
42
42
44
第二个数组包含以下内容:
41
38
38
38
38
38
40
40
41
42
正如您在问题中所写,您能够在输入文件中找到包含所需数据的行。 所以我假设您能够阅读该行并将其存储为std::string
。 以下示例显示如何从std::string
中提取前 10 个数字,用分号分隔并将其添加到std::vector<int>
。
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::string str = "32;39;36;39;39;39;39;42;42;44;46;48;48;49;51;52;54;";
std::vector<int> token_list;
std::string::size_type start_pos = 0;
std::string::size_type pos = 0;
while ((token_list.size() < 10) && ((pos = str.find(";", start_pos)) != std::string::npos))
{
token_list.push_back(std::stoi(str.substr(start_pos, pos - start_pos)));
// Set next start position for search behind found semicolon
start_pos = pos+1;
}
// Print extracted data
for (size_t i = 0; i < token_list.size(); i++)
{
std::cout << token_list[i] << std::endl;
}
return 0;
}
如果您想使用特殊模式将字符串拆分为子字符串,则这称为标记化。 这是一个非常古老的机制,甚至在 C 中也有一个 function strtok
将字符串拆分为令牌。
在 C++ 中还有一个可用的算法,尤其是与容器类合作时。
这就是所谓的std::sregex_token_iterator
。 见这里。 这会遍历std::string
并返回标记。
因此,您应该使用特定且专用的功能。
下一个用于将 n 数据从一个容器复制到另一个容器的专用 function 是std::copy_n
。
这样,整个任务将由一个班轮完成。
从字符串数据到任何数字格式的转换也可以通过专用的 function std::transfrom
transfrom 来完成。
并且 output 也从向量复制到std::cout
。
请看下面的简单示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <regex>
int main() {
// The source values
std::string source{ "32;39;36;39;39;39;39;42;42;44;46;48;48;49;51;52;54;" };
// Here we will store the result
std::vector<std::string> destination{}; // As string
std::vector<int> data{}; // Int, or whatever else you want
// This is the separator betwenn the numbers
std::regex separator{ ";" };
// One-liner to copy 10 sub strings to the destination array
std::copy_n(std::sregex_token_iterator(source.begin(), source.end(), separator, -1), 10, std::back_inserter(destination));
// Convert ot ints (or whatever)
std::transform(destination.begin(), destination.end(), std::back_inserter(data), [](const std::string& s) { return std::stoi(s); });
// And show result on std::cout
std::copy(data.begin(), data.end(), std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
请注意:您当然可以直接将目标数据复制到std::cout
。 用户不会在屏幕上看到差异。 但是如果你想做一些进一步的计算,那么你需要转换。
而且, std::transform
也可以直接写入std::cout
。 如下所示:
std::transform(destination.begin(), destination.end(), std::ostream_iterator<int>(std::cout, "\n"), [](const std::string & s) { return std::stoi(s); });
请注意现代 C++ 算法的美妙之处。 C++20 还有更多功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.