在循环中使用字符串流
Use of stringstream in a loop
如果这堵文字墙过多,我的问题会总结在本页底部。 无论如何,我正在尝试从包含原子及其类型列表的文件中读取行,格式如下:
Li O Ti La
1 24 8 5
这个例子有四个元素和总共 38 个原子,但我正在编写代码以适应任意数量的每个元素。 无论内容如何,元素符号始终在一行上,原子在下一行上。 我认为最好的方法是使用 getline 将每一行插入到一个字符串中,然后使用 stringstream 适当地解析这些字符串。 但事实证明,任意尺寸考虑对我来说是一个问题。 我尝试使用字符串流:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string line;
int num_elements;
struct Element {
string symbol;
int count;
};
Element* atoms_ptr = NULL; //to be allocated
ifstream myfile("filename");
getline(myfile, line);
num_elements = (int)(line.size()/5); //symbols in file have field width 5
atoms_ptr = new Element[num_elements];
for (int i=0; i<num_elements; ++i) {
stringstream(line) >> (*(atoms_ptr+i)).symbol; //does not work
}
getline(myfile, line);
for (int i=0; i<num_elements; ++i) {
stringstream(line) >> (*(atoms_ptr+i)).count; //does not work
}
...
return 0;
}
您可能已经意识到我的字符串流语句的问题。 不是读取四个元素中的每一个元素一次,而是读取四个元素四次。 因此,我的数组每个条目的 .symbol 成员都初始化为 Li。 与原子数类似,.count 成员初始化为 1。
通过以这种方式重建我的循环,我能够编写一些按预期工作的东西:
int j = 3;
for (int i=0; i<num_elements; ++i) {
(*(atoms_ptr+i)).symbol = line.substr(j, 2);
j += 5;
cout << (*(atoms_ptr + i)).symbol << 'n';
}
但是我不喜欢这个解决方案,因为它取决于确切的文件间距,不是特别可读,而且我仍然不知道如何正确使用字符串流。
从根本上说,我认为问题是由于我在循环中使用字符串流引起的。 也许字符串文件指针的位置会在每次迭代时重置? 如果是这样,我需要解决此问题。 我将非常感谢可以提供的任何帮助。 提前感谢!
这应该可以解决问题
#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
#include <vector>
struct Element
{
std::string symbol;
int count;
};
int main()
{
std::ifstream myfile("test.txt");
std::vector<std::string> tokens(
(std::istream_iterator<std::string>(myfile)),
(std::istream_iterator<std::string>()));
myfile.close();
std::vector<Element> elements;
const size_t numEntries = tokens.size() / 2;
for (size_t i = 0; i < numEntries; i++)
{
elements.push_back({ tokens[i], std::stoi(tokens[i+ numEntries]) });
}
return 0;
}
一些解释:
它首先将您的文件内容读入字符串向量(前半部分是元素名称,第二部分是计数( 然后它运行在向量上并将信息聚合到 Element 的向量中(在此过程中将计数转换为整数(
好的,这里有一些建议会对你有所帮助:
- 摆脱
Element
并使用map<string, int>
- 下次使用
istream_iterator
填充
给定希望经过验证的ifstream myfile
和目标输出map<string, int> atoms
,您可以使用如下所示的istream_iterator
:
string line;
getline(myfile, line);
istringstream myline{ line };
transform(istream_iterator<string>{ myline }, istream_iterator<string>{}, istream_iterator<int>{ myfile }, inserter(atoms, end(atoms)), [](const auto& key, const auto& value){ return make_pair(key, value); });
现场示例
- 在循环C++中指定字符串之后,不会打印该字符串
- 在while循环中输入带有std::cin的字符串后,控制台会输出大量胡言乱语
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- C++-字符串是否包含一个带有简单循环的单词
- 在 c++ 中查找字符串中没有循环的数字总和
- 比较两个字符串后卡在无限循环中
- C++ - 使用基于范围的 for 循环将字符值分配给向量中的字符串不会分配值
- 而循环跳过 cin.getline() 对于 C 字符串
- 我正在尝试使用 while 循环从字符串中删除字母,直到没有字母。我在这里做错了什么?
- 如何使用将字符串拆分为 for 循环中的变量的程序
- 是否有可能实现O(N)时间和O(1)空间解决方案,以实现C++中的字符串循环移位
- 循环访问还包含未使用元素的字符串数组
- 循环访问资源字符串表
- C++ - 使用用户输入的字符串数据检查结构字符串数据(无限执行 while 循环)
- 修改向量中的字符串?(不使用循环)
- 试图突破字符串循环
- C++和Java的字符串循环性能比较
- 无法通过字符串循环我的程序以将其从英语翻译成猪拉丁语
- C++ 字符串循环检查相同的单词
- 为什么 javascript 中不使用字符串循环的C++语法?