比较两个向量的<Structs>字符串元素
Comparing string elements of two vector<Structs>
接着我之前的问题:
从 void 函数访问局部变量
从那以后,我已经能够获得我需要的数据,现在我正在尝试比较传递给函数的每个struct
元素的string name
属性。
这是我当前的代码:
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;
struct Nutrient {
string name, units;
double amount, calories;
};
struct Recipe {
string title;
double servings;
};
struct Ingredient {
string name, units;
double amount;
};
vector<Nutrient> readNutrients(istream& fin) {
vector<Nutrient> nutrients;
/**ifstream in(input_file.c_str());*/
string line;
while (getline(fin, line)) {
Nutrient n;
int pos = line.find(';');
n.name = line.substr(0, pos);
line = line.substr(pos + 1);
istringstream iss(line);
iss >> n.amount >> n.units >> n.calories;
nutrients.push_back(n);
}
return nutrients;
}
Recipe readRecipe(istream& fin) {
Recipe recipe;
string line;
int lineCount = 0;
while (getline(fin, line)) {
lineCount++;
istringstream iss(line);
if (lineCount == 1) {
iss >> recipe.title;
}
else if (lineCount == 2) {
iss >> recipe.servings;
}
}
return recipe;
}
vector<Ingredient> readIngredients(istream& fin) {
vector<Ingredient> ingredients;
string line;
string title; // Just grabs, doesnt return
double servings; // Just grabs, doesnt return
int lineCount = 0;
while (getline(fin, line)) {
Ingredient g;
lineCount++;
istringstream iss(line);
if (lineCount == 1) {
iss >> title;
}
else if (lineCount == 2) {
iss >> servings;
}
else {
iss >> g.amount >> g.units >> ws;
getline(iss, g.name, 'n');
cout << g.name << "n";
ingredients.push_back(g);
}
}
return ingredients;
}
bool itemsMatch(vector<Nutrient>& nut, vector<Ingredient>& ing) {
int matchCount = 0;
for (int i = 0; i < nut.size(); i++) {
for (int j = 0; j < ing.size(); j++) {
if (nut[i].name == ing[j].name) {
cout << nut[i].name << " matched " << ing[j].name << endl;
cout << "n";
}
else {
cout << nut[i].name << " didnt match " << ing[j].name << endl;
}
}
}
return true;
}
int main(int argc, char** argv) {
vector<Nutrient> nutri;
vector<Ingredient> ingri;
Recipe rec;
bool match;
ifstream finNutr(argv[1]);
ifstream finIngr(argv[2]);
ifstream finReci(argv[2]);
nutri = readNutrients(finNutr);
ingri = readIngredients(finIngr);
rec = readRecipe(finReci);
match = itemsMatch(nutri, ingri);
return 0;
}
bool itemsMatch()
是造成麻烦的原因。这是最后一个输出:
graham crackers
milk chocolate
marshmallows
graham crackers didnt match graham crackers
graham crackers didnt match milk chocolate
graham crackers didnt match marshmallows
milk chocolate didnt match graham crackers
milk chocolate didnt match milk chocolate
milk chocolate didnt match marshmallows
cheese, swiss didnt match graham crackers
cheese, swiss didnt match milk chocolate
cheese, swiss didnt match marshmallows
marshmallows didnt match graham crackers
marshmallows didnt match milk chocolate
marshmallows matched marshmallows
可见,有几个字符串确实匹配,但由于某种原因它说它们不匹配,我不确定为什么。
参数 1 内容
graham crackers; 2 squares 59
milk chocolate; 1 bar 235
cheese, swiss; 1 oz 108
marshmallows; 1 cup 159
参数2
内容S'mores
2
4 squares graham crackers
1 bar milk chocolate
2 large marshmallows
我的猜测是您的输入文件具有 DOS 行尾,这是两个字符的序列:"rn"
当您使用getline
时,它将读取到n
,因此r
将包含在您从文件中读取的字符串中。这意味着从第二个文件中读取的成分是以下字符串:
S'moresr
2r
4 squares graham crackersr
1 bar milk chocolater
2 large marshmallows
请注意,这在最后一行之后没有"rn"
,因此读取"棉花糖"时没有r
回车符。
在另一个文件中,成分不在行尾,因此r
回车符不会被读入营养的name
字符串中。这意味着当您比较要比较的字符串时:
"graham crackers" == "graham crackersr" -> false
"milk chocolate" == "milk chocolater" -> false
"marshmallows" == "marshmallows" -> true
解决方案是手动剥离r
回车符,或者转换输入文件以删除回车符(或停止使用 Windows,它具有这种愚蠢的约定,会给初学者带来无穷无尽的问题)。
要删除r
字符,您可以在每次getline
后执行此操作:
while (getline(fin, line)) {
if (!line.empty() && line.back() == 'r')
line.pop_back();
这将从行尾删除r
(如果存在)。
或者,如果您停留在过去并且无法使用 C++11:
while (getline(fin, line)) {
if (!line.empty() && line[line.length()-1] == 'r')
line.resize(line.length()-1);
您发布的比较代码很好。当然,你的函数总是返回 true,这没有意义,但这不是问题所在。
问题出在结构体的数据中,因此数据(例如,从中读取的文件)或用于将数据读取到结构体的代码都有缺陷。
要么打印你的结构,确认它们完全包含你认为它们的作用(当然打印你的向量的大小),要么使用调试器,例如gdb。
专业提示:这不是这里的问题,但请考虑更改您的原型:
bool itemsMatch(vector<Nutrient> nut, vector<Ingredient> ing)
对此:
bool itemsMatch(vector<Nutrient>& nut, vector<Ingredient>& ing)
这样,您就不必复制整个向量,而只需传递对它们的引用,这对于大向量来说要快得多! =)
你应该像这样更改代码,然后测试,检查我没有测试的代码的语法:)
auto itring = ing.begin();
for (auto itrnut = nut.begin(); itrnut != nut.end(); itrnut++, itring++ ) {
if (itrnut->name == itring->name) {
cout << itrnut->name << " matched " << itring->name << endl;
cout << "n";
}
}
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- std::memcpy vs std::copy_n for legacy c structs
- 是否有与 C# Structs/StructLayout 等效的功能,C++中的字段偏移量?
- 如何显式调用运算符<<
- 在不复制数据的情况下,将double数组转换为只有double成员的structs数组
- 模板操作员&lt;未打电话
- C / CUDA中的模板方法是3个角括号(&lt;&lt;&lt;)
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 错误:调用"std::vector<:vector<int>>::p ush_back(std::vector<std::__cxx11::basic_string<
- 将 std::list of structs 转换为 Python 列表
- C 建造者Clang STD :: Sill,找不到超载的操作员&lt;
- 为什么STD :: MAP需要操作员&lt;以及我如何写一个
- 为什么“操作员”需要const但不是为“运营商&lt;”
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- 比较两个向量的<Structs>字符串元素
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化