c++ - 在 2D 矢量数组中的特定标题下添加数据
问题描述
假设我们有一个数据,例如:
1A
1
Hi World
2A
2
Hello Bob
Life is Good
3A
0
数据有一个标签1A、2A、3A,这是主标签。在该标签下,它显示该选项卡中的字符串数,即1,2,0,然后是字符串。我们如何在屏幕上显示数据,以便我们分别显示主标签和它下面的字符串?
编码:
vector<string> class_names;
vector<string> data;
ifstream myfile;
myfile.open("file.txt");
string line;
for (int lineno = 1; getline(myfile, line); lineno++) {
if (lineno == 1 || lineno == 4 || lineno == 8) {
class_names.push_back(line); // stores the class names
}
else if (lineno != 2 && lineno != 5 && lineno != 9) {
data.push_back(line); // stores the data in classes
}
}
我在这里所做的是将文件中的数据存储在向量中,它们可以单独打印,但我不能在这个文件中添加另一个类?我们如何将这些数据放在单个向量或 2D 向量中,以便用户可以将数据放入 1A 甚至创建一个新的数据选项卡,如 4A ?那怎么做?
例如,用户需要输入How are you in 1A ,how are you in 1A ,how are you in 1A ?我不打算在代码中提出解决方案,因为我是一个初学者。
解决方案
虽然您可以随心所欲地进行详细说明,但您的基本任务是填充一个对象,该对象存储.tag
之后的下一行指定的字符串数量,然后填充一个字符串向量tag
。该任务更多的是如何验证每个字符串的读取以及tag
与该字符串关联的指定数量的字符串tag
。为了协调数据的存储,您只需要一个存储tag
字符串向量的对象。一个简单的stuct
方法,例如
struct content {
std::string tag; /* storage for tag */
std::vector<std::string> str; /* storage for each string */
};
要处理所有数据,您只需声明 astd::vector<content>
然后使用临时实例content
填充文件中的数据,然后.push_back()
在完成对字符串的读取后将临时结构填充到向量中tag
。
为了让自己清楚您正在为哪个标签读取数据,您将打开文件并读取包含第一行的第一行tag
,例如
...
std::string line; /* storage to read each line */
std::vector<content> contents {}; /* vector of content */
std::ifstream f (argv[1]); /* open file from 1st argument */
while (getline (f, line)) { /* read tag line */
int nstr = 0; /* int for num strings */
content tmp {}; /* temp struct to fill */
tmp.tag = line; /* set .tag in temp struct */
将您tag
存储在临时结构中,将下一行读入int
(或size_t
)值(不要忘记忽略行尾以删除'\n'
输入流中的左侧):
if (!(f >> nstr)) { /* read no. strings as int */
std::cerr << "error: invalid format - nstr.\n";
return 1;
} /* ingore to end of line after nstr read as int */
f.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
将该标记的字符串数存储为int
,只需循环读取与该标记关联的字符串的次数,并将它们添加到临时结构中的字符串向量中(不要忘记验证每次读取):
while (nstr--) { /* loop nstr times */
if (getline (f, line)) /* read line */
tmp.str.push_back(line); /* add to strings stored in temp */
else { /* early EOF reached */
std::cerr << "error: early EOF.\n";
return 1;
}
}
在循环并将每个字符串读入临时结构后,只需.push_back()
将临时结构放入您的永久存储中即可:
contents.push_back(tmp); /* add tmp to contents */
}
现在你有了content
填充向量,你可以以任何你喜欢的方式使用数据。根据您的要求输出字符串tag
,您可以使用一对嵌套的基于范围的for
循环来很好地格式化输出:
for (auto& c : contents) { /* loop over each struct */
std::cout << "\ntag: " << c.tag << '\n'; /* output tag */
for (auto& s : c.str) /* loop over each string */
std::cout << " " << s << '\n'; /* output string */
}
把它放在一个简短的例子中,你可以这样做:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <limits>
struct content {
std::string tag; /* storage for tag */
std::vector<std::string> str; /* storage for each string */
};
int main (int argc, char **argv) {
if (argc < 2) { /* validate 1 argument given for filename */
std::cerr << "usage: " << argv[0] << " <filename>\n";
return 1;
}
std::string line; /* storage to read each line */
std::vector<content> contents {}; /* vector of content */
std::ifstream f (argv[1]); /* open file from 1st argument */
while (getline (f, line)) { /* read tag line */
int nstr = 0; /* int for num strings */
content tmp {}; /* temp struct to fill */
tmp.tag = line; /* set .tag in temp struct */
if (!(f >> nstr)) { /* read no. strings as int */
std::cerr << "error: invalid format - nstr.\n";
return 1;
} /* ingore to end of line after nstr read as int */
f.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
while (nstr--) { /* loop nstr times */
if (getline (f, line)) /* read line */
tmp.str.push_back(line); /* add to strings stored in temp */
else { /* early EOF reached */
std::cerr << "error: early EOF.\n";
return 1;
}
}
contents.push_back(tmp); /* add tmp to contents */
}
for (auto& c : contents) { /* loop over each struct */
std::cout << "\ntag: " << c.tag << '\n'; /* output tag */
for (auto& s : c.str) /* loop over each string */
std::cout << " " << s << '\n'; /* output string */
}
}
(您可以重载>>
以一次性读取临时结构,但代码本质上是相同的,只是移动到content
该重载的成员函数中>>
。这留给您)
示例使用/输出
将您的输入文件另存为dat/2darrtags.txt
,您将执行以下操作:
$ ./bin/read2darrtags dat/2darrtags.txt
tag: 1A
Hi World
tag: 2A
Hello Bob
Life is Good
tag: 3A
如果您还有其他问题,请仔细查看并告诉我。有不止一种方法可以做到这一点。这只是更直接的程序方法之一,您可以根据需要进行改进。
推荐阅读
- python-3.x - 使用最频繁的值按组填充缺失值
- dart - dart removeWhere() - 数据去哪儿了?
- flutter - 找不到名称或 ID 与“emulator-5554”匹配的设备
- typescript - 如何管理多个monorepos
- nullreferenceexception - 我正在使用 Google 图书 API。当我找到“5amclub”时,它显示了这本书的结果,但在找到“Nelson mandela”或“Ramayana”时不显示结果
- ruby-on-rails - Rails 应用程序以点 id 与斜线结尾,如何获得斜线路线?
- django - Django中的链接查询
- python - 将时间序列数据框分成一个有多个变量,每个变量都有年份的名称
- random - 将数据框拆分为子集而不获取因子的重复项
- python-3.x - fastapi中的导入模块错误正在从嵌套路由器导入,它显示错误属性错误模块未找到该文件中的错误