how to iterate over col in 2D vector c++? - c++

I have the following vector of vector containning tree string elements, I want to know how to iterate over col element instead of normal loop over rows
vector<vector<string>> vec2Dstr =
{
{ "A2", "A4", "A6" },
{ "B2", "B4", "B6" },
{ "C2", "C4", "C6" },
{ "D2", "D4", "D6" },
{ "E2", "E4", "E6" }
};
the output expected is :
A2 B2 C2 D2 E2
A4 B4 C4 D4 E4
A6 B6 C6 D6 E6
code
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<vector<string>> vec2Dstr =
{
{ "A2", "A4", "A6" },
{ "B2", "B4", "B6" },
{ "C2", "C4", "C6" },
{ "D2", "D4", "D6" },
{ "E2", "E4", "E6" }
};
for(auto & j : vec2Dstr ) {
for(int i = 0 ; i < 3; i++ )
cout << " => " <<j.at(i) << endl;
}
return 0;
}

this following code might do the aim expected!
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<vector<string>> vec2Dstr =
{
{ "A2", "A4", "A6" },
{ "B2", "B4", "B6" },
{ "C2", "C4", "C6" },
{ "D2", "D4", "D6" },
{ "E2", "E4", "E6" }
};
size_t total_col = vec2Dstr[0].size();
for (int col=0; col<total_col; ++col)
{
for(auto& row : vec2Dstr)
{
cout << row[col] << " ";
}
cout << endl;
}
return 0;
}

Your for loops are wrong. How do you expect it to show 5 elements when you hardcode a limit of 3. Rewrite the for loop using this logic:
Iterate vec2Dstr from 0 to length.
Display vec2Dstr[i][j] where j increases after each loop we described above.
If you still are stuck after this let me know. Show me some code first.

Related

How create a JSON-file from my data? (with ะก++, boost json)

I wanted to create a Json-file that will be created from the data received earlier. I don't understand how to work with Json files at all. I want to use the Boost library, because I am using it in another part of this program. I need to create a Json-file with a specific structure which I have attached below.
I need to get JSON:
{
"track": {
"Wheels": {
"Wheel": [
{
"start_pos": "10",
"end_pos": "25"
},
{
"start_pos": "22",
"end_pos": "78"
}
]
},
"Brakes": {
"Brake": [
{
"start_pos": "10",
"midl_pos": "25"
}
]
}
}
}
C++:
#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/json_parser.hpp"
#include <string>
using namespace std;
using boost::property_tree::ptree;
struct wheel
{
string start_pos;
string end_pos;
};
struct brake
{
string start_pos;
string midl_pos;
};
int main()
{
string tr = "track";
string ws = "Wheels";
string bs = "Brakes";
struct wheel w1;
w1.start_pos = "10";
w1.end_pos = "25";
struct wheel w2;
w2.start_pos = "22";
w2.end_pos = "78";
struct brake b1;
b1.start_pos = "10";
b1.midl_pos = "25";
return 0;
}
Implementing it with the Boost JSON customization points.
Doing it test-driven:
Live On Coliru
#include "boost/json/src.hpp" // header-only approach
#include <iostream>
namespace json = boost::json;
using json::value_from;
using json::value_to;
static const json::value expected = json::parse(R"({
"track": {
"Wheels": {
"Wheel": [
{
"start_pos": "10",
"end_pos": "25"
},
{
"start_pos": "22",
"end_pos": "78"
}
]
},
"Brakes": {
"Brake": [
{
"start_pos": "10",
"midl_pos": "25"
}
]
}
}
})");
namespace MyLib {
struct wheel { int start_pos, end_pos; };
struct brake { int start_pos, midl_pos; };
struct track {
std::vector<wheel> wheels;
std::vector<brake> brakes;
};
void tag_invoke(json::value_from_tag, json::value& jv, wheel const& w) {
jv = {
{"start_pos", std::to_string(w.start_pos)},
{"end_pos", std::to_string(w.end_pos)},
};
}
void tag_invoke(json::value_from_tag, json::value& jv, brake const& b) {
jv = {
{"start_pos", std::to_string(b.start_pos)},
{"midl_pos", std::to_string(b.midl_pos)},
};
}
void tag_invoke(json::value_from_tag, json::value& jv, track const& t) {
jv = {{"track",
{
{"Wheels", {{"Wheel", t.wheels}}},
{"Brakes", {{"Brake", t.brakes}}},
}}};
}
}
int main()
{
MyLib::track track{{
{10, 25},
{22, 78},
},
{
{10, 25},
}};
json::value output = json::value_from(track);
std::cout << output << "\n";
std::cout << expected << "\n";
std::cout << "matching: " << std::boolalpha << (output == expected) << "\n";
}
Prints
{"track":{"Wheels":{"Wheel":[{"start_pos":"10","end_pos":"25"},{"start_pos":"22","end_pos":"78"}]},"Brakes":{"Brake":[{"start_pos":"10","midl_pos":"25"}]}}}
{"track":{"Wheels":{"Wheel":[{"start_pos":"10","end_pos":"25"},{"start_pos":"22","end_pos":"78"}]},"Brakes":{"Brake":[{"start_pos":"10","midl_pos":"25"}]}}}
matching: true
BONUS
Adding full round-trip support. I elected to remove the to_string as it looks like it may have been a requirement from the Boost Property Tree limitations only:
Live On Coliru
#include "boost/json/src.hpp" // header-only approach
#include <iostream>
namespace json = boost::json;
using json::value_from;
using json::value_to;
namespace MyLib {
struct wheel {
int start_pos, end_pos;
bool operator==(wheel const&) const = default;
};
struct brake {
int start_pos, midl_pos;
bool operator==(brake const&) const = default;
};
struct track {
std::vector<wheel> wheels;
std::vector<brake> brakes;
bool operator==(track const&) const = default;
};
void tag_invoke(json::value_from_tag, json::value& jv, wheel const& w) {
jv = {{"start_pos", w.start_pos}, {"end_pos", w.end_pos}};
}
void tag_invoke(json::value_from_tag, json::value& jv, brake const& b) {
jv = {{"start_pos", b.start_pos}, {"midl_pos", b.midl_pos}};
}
void tag_invoke(json::value_from_tag, json::value& jv, track const& t) {
jv = {{"track",
{
{"Wheels", {{"Wheel", t.wheels}}},
{"Brakes", {{"Brake", t.brakes}}},
}}};
}
wheel tag_invoke(json::value_to_tag<wheel>, json::value const& jv) {
return {
value_to<int>(jv.at("start_pos")),
value_to<int>(jv.at("end_pos")),
};
}
brake tag_invoke(json::value_to_tag<brake>, json::value const& jv) {
return {
value_to<int>(jv.at("start_pos")),
value_to<int>(jv.at("midl_pos")),
};
}
track tag_invoke(json::value_to_tag<track>, json::value const& jv) {
auto& track = jv.at("track");
return {
value_to<decltype(track::wheels)>(track.at("Wheels").at("Wheel")),
value_to<decltype(track::brakes)>(track.at("Brakes").at("Brake")),
};
}
}
int main()
{
MyLib::track const track{{
{110, 125},
{111, 126},
{142, 198},
},
{
{10, 25},
{120, 135},
}};
json::value output = json::value_from(track);
std::cout << output << "\n";
std::cout << "Roundtrip: " << std::boolalpha
<< (value_to<MyLib::track>(output) == track) << "\n";
}
Prints
{"track":{"Wheels":{"Wheel":[{"start_pos":110,"end_pos":125},{"start_pos":111,"end_pos":126},{"start_pos":142,"end_pos":198}]},"Brakes":{"Brake":[{"start_pos":10,"midl_pos":25},{"start_pos":120,"midl_pos":135}]}}}
Roundtrip: true
Despite comments suggesting to use a different library, which they could, I think #Nindzzya wanted to specifically use the boost library.
Using the boost library from How to use boost::property_tree to load and write JSON:
#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/json_parser.hpp"
#include <string>
#include <iostream>
using namespace std;
namespace pt = boost::property_tree;
struct wheel
{
string start_pos;
string end_pos;
};
struct brake
{
string start_pos;
string midl_pos;
};
int main()
{
string tr = "track";
string ws = "Wheels";
string bs = "Brakes";
struct wheel w1;
w1.start_pos = "10";
w1.end_pos = "25";
struct wheel w2;
w2.start_pos = "22";
w2.end_pos = "78";
struct brake b1;
b1.start_pos = "10";
b1.midl_pos = "25";
pt::ptree wheel1, wheel2, wheels, wheel;
pt::ptree brake1, brakes, brake;
pt::ptree track, root;
wheel1.put("start_pos", w1.start_pos);
wheel1.put("end_pos", w1.end_pos);
wheel2.put("start_pos", w2.start_pos);
wheel2.put("end_pos", w2.end_pos);
wheels.push_back(make_pair("", wheel1));
wheels.push_back(make_pair("", wheel2));
wheel.add_child("Wheel", wheels);
track.add_child(ws, wheel);
brake1.put("start_pos", b1.start_pos);
brake1.put("midl_pos", b1.midl_pos);
brakes.push_back(make_pair("", brake1));
brake.add_child("Brake", brakes);
track.add_child(bs, brake);
root.add_child(tr, track);
pt::write_json(std::cout, root);
return 0;
}
results in:
{
"track": {
"Wheels": {
"Wheel": [
{
"start_pos": "10",
"end_pos": "25"
},
{
"start_pos": "22",
"end_pos": "78"
}
]
},
"Brakes": {
"Brake": [
{
"start_pos": "10",
"midl_pos": "25"
}
]
}
}
}

C++ removing a element in string array which appears 5 times

Here is the code I have, I am having trouble finding a way to remove all Apple elem in the array. I am able to count the apples in the array. I hope someone can help...
string items[10] = { "Apple", "Oranges", "Pears", "Apple", "bananas", "Apple", "Cucumbers", "Apple", "Lemons", "Apple" };
//Counts the total amount of apples
int n = sizeof(items) / sizeof(items[0]);
cout << "Number of times Apple appears : "
<< count(items, items + n, "Apple");
//remove the element Apple from array
if (string items[].contains("Apple"))
{
items[].remove("Apple");
}
Some options you'd have would be:
Walk your array of items and substitute your "Apple" strings for empty strings.
Use a std::vector of strings and whether a) initialize it with the array of items and then call std::erase_if (C++20) to remove the "Apple" strings, or b) initialize it without elements and then call std::copy_if together with std::back_inserter to append the non-"Apple" strings.
[Demo]
#include <algorithm> // copy_if, transform
#include <iostream> // cout
#include <string>
#include <vector> // erase_if
int main()
{
{
std::string items[10] = { "Apple", "Oranges", "Pears", "Apple", "bananas", "Apple", "Cucumbers", "Apple", "Lemons", "Apple" };
std::transform(std::begin(items), std::end(items), std::begin(items), [](auto& s) {
return (s == "Apple" ? "" : s);
});
for (const auto& s : items) { std::cout << s << ", "; }
std::cout << "\n";
}
{
const std::string items[10] = { "Apple", "Oranges", "Pears", "Apple", "bananas", "Apple", "Cucumbers", "Apple", "Lemons", "Apple" };
std::vector<std::string> v{std::cbegin(items), std::cend(items)};
std::erase_if(v, [](auto& s) { return s == "Apple"; });
for (const auto& s : v) { std::cout << s << ", "; }
std::cout << "\n";
}
{
const std::string items[10] = { "Apple", "Oranges", "Pears", "Apple", "bananas", "Apple", "Cucumbers", "Apple", "Lemons", "Apple" };
std::vector<std::string> v{};
std::copy_if(std::cbegin(items), std::cend(items), std::back_inserter(v), [](auto& s) {
return s != "Apple";
});
for (const auto& s : v) { std::cout << s << ", "; }
}
}
// Outputs:
//
// , Oranges, Pears, , bananas, , Cucumbers, , Lemons, ,
// Oranges, Pears, bananas, Cucumbers, Lemons,
// Oranges, Pears, bananas, Cucumbers, Lemons,
The simplest and most efficient way to remove a number of elements in an array is to create a new array:
#include <iostream>
using namespace std;
int main()
{
string items[10] = { "Apple", "Oranges", "Pears", "Apple", "bananas", "Apple", "Cucumbers", "Apple", "Lemons", "Apple" };
string new_items[10];
int new_size = 0;
// construct new array
for (int i = 0; i < sizeof(items)/sizeof(string); i++) {
if ("Apple" != items[i]) {
new_items[new_size++] = items[i];
}
}
// print new array
for (int i = 0; i < new_size; i++) {
cout << new_items[i] << " ";
}
cout << endl;
return 0;
}

Double dimension array read error

I have a double dimension std::string array which I need to pass as argument of function sortString but I get a runtime error when variable student is first read. "0" is output via cout, but not "1". Any idea of where I am wrong?
Here is my code:
#include <iostream>
#include <string>
void sortString(std::string **student, std::string **output, int size)
{
std::string names[5];
std::cout << "0" << std::endl;
for (int i = 0 ; i < size ; i++)
names[i] = student[i][0];
std::cout << "1" << std::endl;
}
int main()
{
std::string student1 [ ] = {"Joe Lime", "15", "2019"};
std::string student2 [ ] = {"Bob Green", "3", "2020"};
std::string student3 [ ] = {"SallyAnne Green" , "1", "2017"};
std::string student4 [ ] = {"Annie Blue", "10", "2020"};
std::string student5 [ ] = {"Jose Lemon", "25", "2016"};
int const size = 5;
std::string student [5][3] = {student1, student2, student3, student4, student5};
std::string sortedByName[5][3];
sortString((std::string**)student, (std::string**)sortedByName, size);
return 0;
}
** ------------ EDIT ------------ **
I wanted to do the same thing as I do for unidimensional arrays, so I don't understand why it doesn't work for 2-dimensional arrays
e.g, this works :
#include <iostream>
int test(int *a)
{
std::cout << a[0] << std::endl;
}
int main()
{
int a[] = {1,2,3,4,5,6,7};
test(a);
}
int test(int *a)
{
std::cout << a[0] << std::endl;
}
You have a big confusion with arrays, pointers and strings. As #Quentin and
#molbdnilo pointed you out, you are doing a C-style conversion from a bidimensional array of std::strings to a pointer to a pointer to a string, and neither arrays are pointers nor pointers are arrays.
My guess is that you want to sort all the students according to their name, while keeping the rest of the student information associated to the corresponding student.
A couple of advices:
Do not use C-style arrays whenever you can use std::array.
To define the constants in your code, create a constant variable, do not write, for example, 5 as size, this can involve multiple changes in different parts of your code when you want to change that constant value, since it can be written in multiple locations.
You don't need to use pointers in your example. They don't make sense in this scenario.
An example of what you are trying to achieve that uses the std::sort function:
#include <string>
#include <array>
#include <iostream>
#include <algorithm>
const unsigned NUMBER_OF_STUDENTS = 5;
const unsigned NUMBER_OF_STUDENT_DATA_FIELDS = 3;
using studentType = std::array<std::string, NUMBER_OF_STUDENT_DATA_FIELDS>;
int main()
{
std::array<std::string, NUMBER_OF_STUDENT_DATA_FIELDS> student1 = {"Joe Lime", "15", "2019"};
std::array<std::string, NUMBER_OF_STUDENT_DATA_FIELDS> student2 = {"Bob Green", "3", "2020"};
std::array<std::string, NUMBER_OF_STUDENT_DATA_FIELDS> student3 = {"SallyAnne Green" , "1", "2017"};
std::array<std::string, NUMBER_OF_STUDENT_DATA_FIELDS> student4 = {"Annie Blue", "10", "2020"};
std::array<std::string, NUMBER_OF_STUDENT_DATA_FIELDS> student5 = {"Jose Lemon", "25", "2016"};
std::array<studentType, NUMBER_OF_STUDENTS> students = {student1, student2, student3, student4, student5};
std::sort(students.begin(), students.end(), [](const studentType& student1, const studentType& student2) {
// first string in the array is the name
const std::string& nameStudent1 = student1.front();
const std::string& nameStudent2 = student2.front();
// we return if the name of student 1 is lexicographically smaller than the name of student 2
return nameStudent1 < nameStudent2;
});
// Let's print the students to see we have order everything correctly
for (const auto& student: students) // for each student
{
for (const auto& studentData : student) // for each field in the student string
{
std::cout << studentData << " ";
}
std::cout << "\n"; // jump to the next line
}
}
Annie Blue 10 2020
Bob Green 3 2020
Joe Lime 15 2019
Jose Lemon 25 2016
SallyAnne Green 1 2017
i fixed your code a bit and got it to work:
#include <iostream>
#include <string>
void sortString(std::string student[][3], std::string output[][3], int size)
{
std::string names[5];
std::cout << "0" << std::endl;
for (int i = 0; i < size; i++)
{
names[i] = student[i][0];
std::cout << names[i] << "\n";
}
std::cout << "1" << std::endl;
}
int main()
{
int const size = 5;
std::string students[5][3] =
{
{ "Joe Lime", "15", "2019" },
{ "Bob Green", "3", "2020" },
{ "SallyAnne Green", "1", "2017" },
{ "Annie Blue", "10", "2020" },
{ "Jose Lemon", "25", "2016" }
};
std::string sortedByName[5][3];
sortString(students, sortedByName, size);
return 0;
}
but i highly recommend you use arrays, vectors and structs/classes. following a made up an example with vector and arrays and vector and structs
#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <algorithm>
void sortString(std::vector<std::array<std::string, 3>>& students)
{
// for example: print all names with range base for loop
for (const auto& s : students)
{
std::cout << s[0] << std::endl;
}
// for example: print all names with "normal" for loop
for (std::size_t i = 0; i < students.size(); ++i)
{
std::cout << students[i][0] << std::endl;
}
// sort by name
std::sort(std::begin(students), std::end(students), [](const std::array<std::string, 3>& a, const std::array<std::string, 3>& b){ return a[0] < b[0]; });
}
int main()
{
int const size = 5;
std::vector<std::array<std::string, 3>> students;
students.push_back({ "Joe Lime", "15", "2019" });
students.push_back({ "Bob Green", "3", "2020" });
students.push_back({ "SallyAnne Green", "1", "2017" });
students.push_back({ "SallyAnne Green", "1", "2017" });
students.push_back({ "Jose Lemon", "25", "2016" });
sortString(students);
return 0;
}
with struct:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
struct Student
{
std::string name;
std::string dontKnow;
std::string year;
};
void sortString(std::vector<Student>& students)
{
// for example: print all names with range base for loop
for (const auto& s : students)
{
std::cout << s.name << std::endl;
}
// for example: print all names with "normal" for loop
for (std::size_t i = 0; i < students.size(); ++i)
{
std::cout << students[i].name << std::endl;
}
// sort by name
std::sort(std::begin(students), std::end(students), [](const Student& a, const Student& b){ return a.name < b.name; });
}
int main()
{
int const size = 5;
std::vector<Student> students;
students.push_back({ "Joe Lime", "15", "2019" });
students.push_back({ "Bob Green", "3", "2020" });
students.push_back({ "SallyAnne Green", "1", "2017" });
students.push_back({ "SallyAnne Green", "1", "2017" });
students.push_back({ "Jose Lemon", "25", "2016" });
sortString(students);
return 0;
}
i hope you see how much cleaner your code gets

creating nested json object in c++ using nlohmann json

I am working with https://github.com/nlohmann/json and it works well. However I am finding difficulties to create the following json outout
{
"Id": 1,
"Child": [
{
"Id": 2
},
{
"Id": 3,
"Child": [
{
"Id" : 5
},
{
"Id" : 6
}
]
},
{
"Id": 4
}
]
}
Every node must have an id and an array ("Child" element). Any child can recursively continue to have Id or Child. The json above is just an example. What I want is to create a chain between father and children node using nlohmann json.
Numbers 1, 2, 3, .... are picked up randomly. We don't care for now about those values.
Any idea how to create it?
Code so far
#include <iostream>
#include <string>
#include <vector>
#include "json.hpp"
using json = nlohmann::json;
struct json_node_t {
int id;
std::vector<json_node_t> child;
};
int main( int argc, char** argv) {
json j;
for( int i = 0; i < 3; i++) {
json_node_t n;
n.id = i;
j["id"] = i;
if ( i < 2 ) {
j["child"].push_back(n);
}
}
return 0;
}
In order to serialize your own type, you need to implement a to_json function for that type.
#include <iostream>
#include <string>
#include <vector>
#include "json.hpp"
using namespace std;
using json = nlohmann::json;
struct json_node_t {
int id;
std::vector<json_node_t> child;
};
void to_json(json& j, const json_node_t& node) {
j = {{"ID", node.id}};
if (!node.child.empty())
j.push_back({"children", node.child});
}
int main() {
json_node_t node = {1, {{2, {}}, {3, {{5, {}}, {6, {}}}}, {4, {}}}};
json j = node;
cout << j.dump(2) << endl;
return 0;
}
Output:
{
"ID": 1,
"children": [
{
"ID": 2
},
{
"ID": 3,
"children": [
{
"ID": 5
},
{
"ID": 6
}
]
},
{
"ID": 4
}
]
}
A couple of more ways to initialize json_node_t (all producing the same tree and the same output):
struct json_node_t {
int id;
std::vector<json_node_t> child;
json_node_t(int node_id, initializer_list<json_node_t> node_children = initializer_list<json_node_t>());
json_node_t& add(const json_node_t& node);
json_node_t& add(const initializer_list<json_node_t>& nodes);
};
json_node_t::json_node_t(int node_id, initializer_list<json_node_t> node_children) : id(node_id), child(node_children) {
}
json_node_t& json_node_t::add(const json_node_t& node) {
child.push_back(node);
return child.back();
}
json_node_t& json_node_t::add(const initializer_list<json_node_t>& nodes) {
child.insert(child.end(), nodes);
return child.back();
}
int main() {
json_node_t node_a = {1, {{2, {}}, {3, {{5, {}}, {6, {}}}}, {4, {}}}};
json_node_t node_b = {1, {2, {3, {5, 6}}, 4}};
json_node_t node_c(1);
node_c.add(2);
node_c.add(3).add({5, 6});
node_c.add(4);
cout << json(node_a).dump(2) << endl << endl;
cout << json(node_b).dump(2) << endl << endl;
cout << json(node_c).dump(2) << endl;
return 0;
}

Code for finding string between "" in a data structure

I need help to solve the following:
Lets say I have the number 70368 in int var and that I want to find the corresponding string "EVT_ACP_CAPT_MIC_FLT" in the structure below and load it ( including the "") to a
char* event variable
The code solution must work for any number lenght between 1 to 5.
struct NameOffset TestEvents[] = {
{ "EVT_ACP_CAPT_LAST1", 70387 },
{ "EVT_ACP_CAPT_LAST1", 70387 },
{ "EVT_ACP_CAPT_LAST2", 70512 },
{ "EVT_ACP_CAPT_LAST2", 70512 },
{ "EVT_ACP_CAPT_MASK_BOOM_SWITCH", 70385 },
{ "EVT_ACP_CAPT_MIC_FLT", 70368 },
{ "EVT_ACP_CAPT_MIC_HF1", 70510 },
{ "EVT_ACP_CAPT_MIC_HF2", 70511 },
};
The table is in real very long, this is just a few lines to show the structure.
Assuming that the fields of struct NameOffset are Name and Offset, you can find a match using a loop, like this:
for (int i = 0 ; i != sizeof(TestEvents)/sizeof(struct NameOffset) ; i++) {
if (PmdgEvents[i].Offset == intVar) {
printf("%s\n", PmdgEvents[i].Name);
break;
}
}
The brute-force approach is to use a loop and compare the second struct member to identigfy the right struct.
If the code will be executed regularly, you should use a unordered_map: load the data to a unordered_map<int, string> (or char * instead of string if you like) and then use
event_map[code];
to access the string.
#include <unordered_map>
#include <iostream>
using namespace std;
struct NameOffset {
const char *event;
int code;
};
struct NameOffset TestEvents[] = {
{ "EVT_ACP_CAPT_LAST1", 70387 },
{ "EVT_ACP_CAPT_LAST2", 70512 },
{ "EVT_ACP_CAPT_MASK_BOOM_SWITCH", 70385 },
{ "EVT_ACP_CAPT_MIC_FLT", 70368 },
{ "EVT_ACP_CAPT_MIC_HF1", 70510 },
{ "EVT_ACP_CAPT_MIC_HF2", 70511 },
};
#define N_ELEMENTS (sizeof(TestEvents) / sizeof(NameOffset))
int main() {
unordered_map<int, const char *> event_map;
for (NameOffset *it = TestEvents, *it_end = TestEvents + N_ELEMENTS;
it != it_end; ++it) {
event_map[it->code] = it->event;
}
cout << event_map[70387] << endl;
cout << event_map[70512] << endl;
cout << event_map[70385] << endl;
cout << event_map[70368] << endl;
cout << event_map[70510] << endl;
cout << event_map[70511] << endl;
return 0;
}
Create a Map of <int,string> and then index the map with the corresponding value you want to search
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main (){
std::pair<int,string> TestEvents[] = {
make_pair( 70387,"EVT_ACP_CAPT_LAST1" ),
make_pair( 70???,"EVT_ACP_CAPT_LAST1" ),
make_pair( 70512,"EVT_ACP_CAPT_LAST2" ),
make_pair( 70512,"EVT_ACP_CAPT_LAST2" ),
make_pair( 70385, "EVT_ACP_CAPT_MASK_BOOM_SWITCH" ),
make_pair( 70368,"EVT_ACP_CAPT_MIC_FLT" ),
make_pair( 70510,"EVT_ACP_CAPT_MIC_HF1" ),
make_pair( 70511,"EVT_ACP_CAPT_MIC_HF2" )
};
map<int,string> mapTestEvents(TestEvents,TestEvents + sizeof TestEvents / sizeof TestEvents[0]);
int var = 70368;
const char* event = mapTestEvents[var].c_str();
return 0;
}
Please note, I assume the integer value is unique else the whole problem statement would be void.
And yet another way to do it using std::sort and std::lower_bound
#include<iostream>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
struct NameOffset {
string name;
int offset;
};
NameOffset TestEvents[] = {
{ "EVT_ACP_CAPT_LAST1", 70387 },
{ "EVT_ACP_CAPT_LAST1", 70387 },
{ "EVT_ACP_CAPT_LAST2", 70512 },
{ "EVT_ACP_CAPT_LAST2", 70512 },
{ "EVT_ACP_CAPT_MASK_BOOM_SWITCH", 70385 },
{ "EVT_ACP_CAPT_MIC_FLT", 70368 },
{ "EVT_ACP_CAPT_MIC_HF1", 70510 },
{ "EVT_ACP_CAPT_MIC_HF2", 70511 },
};
bool CompareByEvent(NameOffset const& lhs, NameOffset const& rhs) {
return lhs.offset < rhs.offset;
}
int main (){
sort(TestEvents,TestEvents + sizeof TestEvents / sizeof TestEvents[0], &CompareByEvent);
NameOffset var = {"",70510};
const char* event =lower_bound(TestEvents,TestEvents + sizeof TestEvents / sizeof TestEvents[0], var,&CompareByEvent)->name.c_str();
return 0;
}