bool find function did not search in array - c++

I want to make find function for my class that searches an array of items and return 1 if it is found and return 0 otherwise.
Here my code but always returns 0:
// implementation file
bool bag::find(string item_name)
{
for (int i = 0; i < 5; i++)
if (arr[i] == item_name)
return true;
return false;
}
string arr[5]={"a","b","c","d","e"}
max size of array is 5
// main
cout << find("a");
How I can make it search correctly?

Just use std::find:
bool bag::find(std::string item)
{
return std::find(arr, arr + 5, item) != &arr[5];
}
I'm assuming arr is a C-style array until you say otherwise.

If you defined your array as having element type char then indeed your function will not work because an object of type char can not be implicitly converted to type std::string.

Related

C++: Char pointer to char pointer array to char array

I'll do my best to be brief:
So I have an assignment where I am creating a 'Wordlist' class. In which I will store a list of words.
These are the member variables
class WordList
{ //...
unsigned int m_count; // Number of words currently in list
unsigned int m_max; // The total size of the list.
char** m_list; // The list storing the words
};
This is my constructor
WordList::WordList(const int max_words) {
if(max_words < 1){
m_list = nullptr;
m_max = 0;
m_count = 0;
}
else
m_list = new char*[max_words];
m_count = 0;
m_max = max_words;
for (int i = 0; i < max_words; i++) {
m_list[i] = new char[20];
}
}
And this is where I start to find problems.
The following add function is supposed to add a word in the form of a c-style string that is pointed to from the array of character pointers that is pointed to from **char m_list .
int WordList::add(const char word[]) {
if (m_count == 0 && m_list != nullptr ) {
strcpy (m_list[m_count], word);
m_count++;
return 0;
}
if (m_count < m_max) {
m_count++;
strcpy (m_list[m_count], word);
return 0;
}
if (m_count == m_max) {
m_count++;
m_max ++;
strcpy (m_list[m_count], word);
return 1;
}
if (strlen(word)==0) {
return -2;
}
if (m_list == nullptr ){
return -2;
}
else
return -2;
}
So the issue I am having is that I clearly not syntactically correct with my * because I am not getting an array of 5 pointers that point to full words rather I am getting the first letter saved to the final destination char but its not copying over everything like I want.
I'm sure I didn't translate my problem to English as well as I should have but hopefully thats a start. Thank you!
An example of how I will be calling my add function:
WordList *wordlist = new WordList(5);
wordlist->add("harry");
wordlist->add("ron");
wordlist->add("hermione");
And it should add to the bottom of the pointer array a pointer to each word
so
cout << wordlist->m_list[0][2] << endl; // Expect 'r'
cout << wordlist->m_list[1] << endl; // Expect "ron"
instead I get
r
printed out only
I don't see anything wrong with your use of double-pointers.
There are other issues, though:
in your WordList::add you should check for empty word or empty list first, and fail fast. Besides, in your code if the word was empty - you would already added it and returned form that function.
in if (m_count < m_max) block, you pre-increment m_count, leaving one element empty and risking to go out-of-bounds on the last entry.
in if (m_count == m_max) { you are CERTAINLY going out-of-bounds
Suggestion: instead of pre-allocating 20-character arrays, leave them nullptr; when you need to a word - use strdup(word); that would allocated a required space for you.
As for your I am getting the first letter saved - I am guessing you are not checking it right...
The problem is that you add the first word:
if (m_count == 0 && m_list != nullptr ) {
strcpy (m_list[m_count], word);
m_count++;
return 0;
}
Which increments m_count so now m_count is 1.
Then you add the second word:
if (m_count < m_max) {
m_count++;
strcpy (m_list[m_count], word);
return 0;
}
Which increments m_count BEFORE adding the word so the second word is at index 2 and index 1 is skipped altogether.
You need to always increment the count after copying the word because m_count is 1 based and the array is 0 based.

Get index of element in a struct c++

I want to get the index of an element in a struct.Below is the code. However it is only returning 0 as the output. Assuming I have added data to the struct below, the function find_index does not return the index of the element.It only returns 0;
struct Person{
string name;
int age;
float spread_prob;
float disease_prob;
float recover_prob;
status disease_status;
int sick_day;
};
Person person[9];
int find_index(string m){
for(i=0;i<9;i++){
if(m==person[i].name){
return i;
}
}
return 0;
}
The return 0 is inside your for-loop. So when the first iteration match, return i is return 0 and if this is not the case return 0 is called. Move the return 0 out of your loop, so the loop will not break after one iteration.
Firstly, your code has syntactical errors such as the loop variable i being not defined and logical errors such as returning 0 inside the for-loop, (which means that irrespective of any index match, your function will only return 0) and returning 0 itself is an error since that implies your string or name is found at the first index. If your not following array indices, consider adding a +1 to the return statement. Otherwise, use something else, such as a -1 or any negative number to indicate that the string is not found/matched in any index.
Next, your code is not defined under proper scope for a minimal reproducible example (one which can be directly copy-pasted and tested on our compilers).
Considering the Person objects are in main(), I have created a lambda / temporary-function inside the main scope which should help you solve your problem: (considering struct's name member and an array of 3 Person objects for demonstration)
#include <iostream>
struct Person
{
std::string name;
};
int main()
{
Person person[3];
person[0].name = "Karl";
person[1].name = "John";
person[2].name = "Felix";
auto findIndex = [=](std::string m)
{ for(int i = 0; i < 3; i++)
{ if(m == person[i].name)
return i;
}
return -1;
};
std::cout << findIndex("Felix");
std::cout << "\n";
std::cout << findIndex("Blaze");
}
Output :
2
-1
int find_index(string m){
int ret = -1; // -1 denotes not available
for(i=0;i<9;i++){
if(m==person[i].name){
ret = i;
break;
}
}
return ret ; //If it matches it will return the index on which it breaks.
}
You can use a return variable.

C++ There is a bool return type function returning (24) here

First of all sorry for too much code
Here there is a vector (teamNum) with type class, the class contain a vector (player) with type struct, it is a little complicated, but here in this function I need to check if there is a player in teamNum which contain tName equal to _tname (function parameter) contain (the player) pID equal to _pID (function parameter)
bool thereIsSimilarID(string _tname, int _pID)
{
for (int i = 0; i < teamNum.size(); i++)
{
if (teamNum[i].tName == _tname)
{
for (int j = 0; j < teamNum[i].player.size(); j++)
{
if (teamNum[i].player[j].pID == _pID)
return true;
}
}
else if (i == (teamNum.size() - 1))
{
return false;
}
}
}
And in the main
int main()
{
cout << "\n" << thereIsSimilarID("Leverpool", 1) << endl;
}
The output is 24 !!!!!
(good note that this happen just when the team (Leverpool) is the last team in the vector teamNum)
Again sorry for too much code but I need to know the bug not only fix the problem I need to learn from you
You encountered undefined behaviour.
If you take the if (teamNum[i].tName == _tname)-branch on the last element, but find no player with the correct pID, you don't return anything. Which means, that the return value is whatever random value is currently in the memory location that should hold the return value. In your case it happens to 24. But theoretically, everything could happen.
The same problem occurs when teamNum is empty.
The solution is to make sure to always return a value from a function (except if it has return type void of course):
bool thereIsSimilarID(string _tname, int _pID)
{
for (int i = 0; i < teamNum.size(); i++)
{
// In this loop return true if you find a matching element
}
// If no matching element was found we reach this point and make sure to return a value
return false;
}
You should take a look at your compiler settings and enable all the warnings. And often it's good to let it treat certain warnings as errors.

g++ compiler is not recognizing my function

I'm just starting to code, and am learning about arrays right now. I am trying to write a program that takes in a list of arrays, and tells me if the first or last number is a 2. To do this, I'm using a function.
My code looks like:
#include <iostream>
using namespace std;
const int size = 6;
bool firstlast(int array[size]);
int main()
{
int array[size];
for (int index = 0; index < size; index++)
{
cout << "Enter value for array[" << index << "]\n";
cin >> array[index];
}
bool check = firstlast(array[size]);
if (check)
cout << "The array either starts or ends in 2!\n";
else
cout << "The array does not start or end with 2.\n";
return 0;
}
bool firstlast(int array[size])
{
if (array[0] == 2)
return true;
if (array[size - 1] == 2)
return true;
return false;
}
What am I doing wrong?
The compiler gives me the error:
candidate function not viable: no known conversion from 'int' to 'int *' for 1st argument; take the address of the argument with and
The compiler is recognising your function fine.
The problem is in the manner your code calls the function
bool check = firstlast(array[size]);
which attempts to pass array[size] (a non-existent element of array) to a function expecting a pointer.
The call, presumably, should be
bool check = firstlast(array);
since arrays are implicitly converted to pointers when passed to functions.
This code
bool check = firstlast(array[size], size);
tries to pass the sizeth element of array not the array itself. In C++ arrays are passed by pointer, even if you write the function parameter with array syntax.
To avoid confusing yourself, change firstlast to
bool firstlast`(int* array, int size)`
and call it with
bool check = firstlast(array, size);

How can I return an array?

Is there any way to return an array from a function? More specifically, I've created this function:
char bin[8];
for(int i = 7; i >= 0; i--)
{
int ascii='a';
if(2^i-ascii >= 0)
{
bin[i]='1';
ascii=2^i-ascii;
}
else
{
bin[i]='0';
}
}
and I need a way to return bin[].
You can't do that but you can:
return a dynamicaly allocated array - best owned by a smart pointer so that the caller does not have to care about deallocating memory for it - you could also return something like an std::vector this way.
populate an array/vector passed to you as an argument by pointer (suggested) or a non const reference.
Your array is a local variable allocated on the stack. You should use new [] to allocate it on the heap. Then you can just say: return bin;. Beware that you will have to explicitly free it with delete [] when you are done with it.
You are really asking the wrong question. If you want to do string processing in C++, use the std::string and/or std::vector classes, not arrays of char. Your code then becomes:
vector <char> func() {
vector <char> bin(8);
for( int i = 7; i >= 0; i-- ) {
int ascii='a';
if ( 2 ^ i - ascii >= 0 ) {
bin[i] = '1';
ascii = 2^i - ascii;
}
else {
bin[i] ='0';
}
}
return bin;
}
I think your best bet is to use a vector. It can function in many ways like an array and has several upsides (length stored with type, automatic memory management).
void Calculate( std::vector<char>& bin) {
for(int i = 7; i >= 0; i--)
{
int ascii='a';
if(2^i-ascii >= 0)
{
bin.push_back('1');
ascii=2^i-ascii;
}
else
{
bin.push_back('0');
}
}
}
If you want to return a copy of the array (might make sense for small arrays) and the array has fixed size, you can enclose it in a struct;
struct ArrayWrapper {
char _bin[8];
};
ArrayWrapper func()
{
ArrayWrapper x;
// Do your stuff here using x._bin instead of plain bin
return x;
}
Or just use a std::vector as has been already suggested.
Similar implemented to #ari's answer, i want to say there is already a boost solution, boost::array solving your problem:
boost::array<char, 8> f() {
boost::array<char, 8> bin;
for(int i = 7; i >= 0; i--) {
int ascii = 'a';
if(2 ^ i-ascii >= 0) {
bin[i] = '1';
ascii = 2 ^ i-ascii;
} else {
bin[i] = '0';
}
}
}
...
boost::array<char, 8> a(f());
[I'm not sure what you want to do with that algorithm though, but note that i think you want to do 1 << i (bit-wise shift) instead of 2 ^ i which is not exponentiation in C++.]
Boost array is a normal array, just wrapped in a struct, so you lose no performance what-so-ever. It will also be available in the next C++ version as std::array, and is very easy to do yourself if you don't need the begin()/size()/data()-sugar it adds (to be a container). Just go with the most basic one:
template<typename T, size_t S>
struct array {
T t[S];
T& operator[](ptrdiff_t i) { return t[i]; }
T const& operator[](ptrdiff_t i) const { return t[i]; }
};
But as usual, use the tools already written by other people, in this case boost::array. It's also got the advantage of being an aggregate (that's why it has no user declared constructor), so it allows initializing with a brace enclosed list:
boost::array<int, 4> a = {{ 1, 2, 3, 4 }};
you need to pass array bin as an argument in your function.
array always pass by address, therefore you dont need to return any value.
it will automatically show you all changes in your main program
void FunctionAbc(char bin[], int size);
void FuncationAbc(bin, size)
{
for(int i = 7; i >= 0; i--)
{
int ascii='a';
if(2^i-ascii >= 0)
{
bin[i]='1';
ascii=2^i-ascii;
}
else
{
bin[i]='0';
}
}
}
You'll want to pass by reference, as follows:
void modifyBin(char (&bin)[8])
{
/* your function goes here and modifies bin */
}
int main()
{
char bin[8];
modifyBin(bin);
/* bin has been updated */
return 0;
}
I think that everyone else answered this one... use a container instead of an array. Here's the std::string version:
std::string foo() {
int ascii = 'a';
std::string result("00000000");
for (int i=7; i>=0; --i) {
if (2^i-ascii >= 0) {
result[i] = '1';
ascii = 2^i-ascii;
}
}
return result;
}
I'm not really sure if 2^i-ascii is want you want or not. This will be parsed as (2 ^ (i - ascii)) which is a little strange.