C++ - Error while usign arrays as parameter - c++

I made a array of words and made a function to return a random word from the array. But it shows this error -
hangman.cpp: In function 'std::__cxx11::string get_random_word(std::__cxx11::string*)':
hangman.cpp:17:33: warning: 'sizeof' on array function parameter 'words' will return size of 'std::__cxx11::string* {aka std::__cxx11::basic_string<char>*}' [-Wsizeof-array-argument]
size_t length = sizeof(words) / sizeof(words[0]);
^
hangman.cpp:15:47: note: declared here
std::string get_random_word(std::string words[])
^
Here is the code -
#include <iostream>
#include <string>
#include <ctime>
std::string get_random_word(std::string words[]);
int main()
{
srand(time(0));
std::string words[] = {"cpp", "python", "java"};
std::cout << get_random_word(words);
return 0;
}
std::string get_random_word(std::string words[])
{
size_t length = sizeof(words) / sizeof(words[0]);
return words[rand() % length];
}

The sizeof operator may not be doing exactly what you think. According to cppreference: (sizeof) Yields the size in bytes of the object representation of type. This may include any internal members needed for the class, and not just how many characters are used in the string for example. std::string has the size() and length() functions for this, which are the same, and instead of using an array you can use a vector that also provides a size() function.
#include <iostream>
#include <string>
#include <ctime>
#include <vector>
std::string get_random_word(std::vector<std::string>& words)
{
return words[rand() % words.size()];
}
int main()
{
srand(time(0));
std::vector<std::string> words = {"cpp", "python", "java"};
std::cout << get_random_word(words);
return 0;
}

Related

std::string::insert doesn't work with to_string(). CPP

I am writing a code to insert an integer at an index of the string, but after providing the integer to add as string, insert function is not giving the correct output.
It is giving the error that :
no matching member function to call for insert string
This is my code:
#include <iostream>
using namespace std;
int main()
{
string s = "45564528";
int x = 8;
s.insert(s.begin()+5,to_string(x));
cout<<s<<endl;
return 0;
}
The expected output is 455648528.
Looking at the documentation for std::string::insert() shows that it takes a char or an iterator range, not a std::string, which std::to_string() naturally returns. At least, this is the case for the overloads that take an iterator for the first argument.
#include <iostream>
#include <string> // CHANGED: Include what you use
// using namespace std; // CHANGED: Bad practice
int main()
{
std::string s = "45564528";
int x = 8;
// CHANGED: Create string from the int, and use the iterator range overload
// to account for multi-digit numbers
auto tmp = std::to_string(x);
s.insert(s.begin()+5, tmp.begin(), tmp.end());
std::cout << s << '\n'; // CHANGED: std::endl is rarely actually needed
return 0;
}
There is an overload that lets you insert another std::string, but the first argument must be an index and not an iterator. So this would work as well:
#include <iostream>
#include <string>
int main()
{
std::string s = "45564528";
int x = 8;
s.insert(5, std::to_string(x));
std::cout << s << '\n';
return 0;
}

Limiting total size of result with C++20 fmt

I know I can limit the size of a particular string argument, but IDK how to do it for the entire output.
In other words can this program be written with only one call to format?
#include <string>
#include <iostream>
#include <fmt/format.h>
int LOG_MAX_MESSAGE_LENGTH = 11;
void f(const char* p) {
std::cout << fmt::format("{:.{}}", fmt::format("ABI is {}", p),
LOG_MAX_MESSAGE_LENGTH)
<< std::endl;
}
int main() {
f("hellooooo");
}
There's also format_to_n, which takes an output iterator and a size (and then the usual format string and arguments).
format_to_n(
std::ostream_iterator(std::cout), LOG_MAX_MESSAGE_LENGTH,
"ABI is {}", p);

char and char& no matching function for call

In order to compare if two string contain a same char, I was trying to loop through a string a and put the chars into a map.
So this is what I did.
string a = "abc";
unordered_map<char,int> m;
for (auto i:a){
m.insert(i,1);
}
But then there is an error:
no matching function for call to ‘std::unordered_map<char, int>::insert(char&, int)’
I don't quite understand what can I do here. Hope someone can help!
The problem in your code is that you try to insert a which is a std::string into an std::unordered_map<char, int> - you should be inserting i which is a char (each char from std::string a).
Moreover, even if you correctly used
m.insert(a,1);
it wouldn't compile because std::unordered_map::insert accepts a std::pair not 2 arguments from the template type. So you would need:
std::unordered_map<char, int> char_map;
char_map.insert(std::make_pair(c, 1));
Want you want to achieve can be done with std::set (if you don't care about the order of objects - chars - stored inside it)
#include <iostream>
#include <string>
#include <unordered_set>
int main()
{
std::string a = "abc";
std::unordered_set<char> char_set;
for (auto c : a)
char_set.insert(c);
for (auto c : char_set)
std::cout << c << ' ';
}
http://cpp.sh/3zrgr
Unfortunately you need to call std::make_pair first:
#include <iostream>
#include <unordered_map>
int main()
{
std::string a = "abc";
std::unordered_map<char,int> m;
for (int i = 0; i < a.size(); ++i)
m.insert(std::make_pair(a[i],1));
}

How to use qsort for string in C++

I want to use qsort function to sort the characters in the strings using C++.
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
int compare_str(void const *a,void const *b){
char const *aa=(char const *)a;
char const *bb=(char const *)b;
if(*aa==*bb) return 0;
else if(*aa>*bb) return 1;
else return -1;
}
int main(){
string str="cake";
int len=str.length();
qsort(str,len,sizeof(str[0]),compare_str);
cout<<str;
return 0;
}
But it throws :
20 42 [Error] cannot convert 'std::string {aka std::basic_string<char>}' to 'void*' for argument '1' to 'void qsort(void*, size_t, size_t, int (*)(const void*, const void*))'
It would be great if anyone could provide an efficient way to do this.
I strongly recommend the modern method of
#include <algorithm>
#include <iostream>
#include <string>
int main()
{
std::string s("cake");
std::sort(s.begin(), s.end());
std::cout << s << std::endl; // Prints "acek".
return 0;
}
Plus, using std::sort over qsort allows the compiler to optimize better, so it's a win-win...
Your comparator for qsort expects C strings, not C++ std::strings. You should either declare str to be char str[]
char str[] = "cake";
qsort(str, strlen(cake), sizeof(char), compare_str); // Consider renaming to compare_char
or (better) use std::sort:
string str = "cake";
sort(str.begin(), str.end());
If you really want to do this, just pass a pointer to the string's contents:
qsort(str.c_str(),len,sizeof(str[0]),compare_str);
That said, you really should consider using the functions provided in the STL rather than those from the old C library...
You should use the function sort() under the header <algorithm>. This function is very flexible and you can use it in different manner. For sorting as you wish in question you can just write:
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s="cake";
sort(s.begin(), s.end());
cout << s << endl;
return 0;
}
//output: acek
again by using sort() we can implement it in a range. If you want to sort first two element , the code will be
sort(s.begin(), s.begin()+2);
for above code the output will be
//output: acke
so if we want to sort first n element then we can write
sort(s.begin,s.begin()+n);
we can also modify the sort function. In that case we have to pass three parameter instead of two. The third parameter will be a functions which returns a bool value.For example , if we want to sort in descending order then our code will be like this
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
bool desc(char i, char j)
{
return i>j;
}
int main()
{
string s="cake";
sort(s.begin(), s.end(),desc);
cout << s << endl;
return 0;
}
//output: keca
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
int compare_str(void const *a,void const *b){
char const *aa=(char const *)a;
char const *bb=(char const *)b;
if(*aa==*bb) return 0;
else if(*aa>*bb) return 1;
else return -1;
}
int main(){
string str="cake";
int len=str.length();
qsort(const_cast<char*>(str.c_str()),len,sizeof(str[0]),compare_str);
cout<<str<<endl;
return 0;
}

Converting an int to std::string

What is the shortest way, preferably inline-able, to convert an int to a string? Answers using stl and boost will be welcomed.
You can use std::to_string in C++11
int i = 3;
std::string str = std::to_string(i);
#include <sstream>
#include <string>
const int i = 3;
std::ostringstream s;
s << i;
const std::string i_as_string(s.str());
boost::lexical_cast<std::string>(yourint) from boost/lexical_cast.hpp
Work's for everything with std::ostream support, but is not as fast as, for example, itoa
It even appears to be faster than stringstream or scanf:
http://www.boost.org/doc/libs/1_53_0/doc/html/boost_lexical_cast/performance.html
Well, the well known way (before C++11) to do that is using the stream operator :
#include <sstream>
std::ostringstream s;
int i;
s << i;
std::string converted(s.str());
Of course, you can generalize it for any type using a template function ^^
#include <sstream>
template<typename T>
std::string toString(const T& value)
{
std::ostringstream oss;
oss << value;
return oss.str();
}
If you cannot use std::to_string from C++11, you can write it as it is defined on cppreference.com:
std::string to_string( int value )
Converts a signed decimal integer to a string with the same content as what std::sprintf(buf, "%d", value) would produce for sufficiently large buf.
Implementation
#include <cstdio>
#include <string>
#include <cassert>
std::string to_string( int x ) {
int length = snprintf( NULL, 0, "%d", x );
assert( length >= 0 );
char* buf = new char[length + 1];
snprintf( buf, length + 1, "%d", x );
std::string str( buf );
delete[] buf;
return str;
}
You can do more with it. Just use "%g" to convert float or double to string, use "%x" to convert int to hex representation, and so on.
Non-standard function, but its implemented on most common compilers:
int input = MY_VALUE;
char buffer[100] = {0};
int number_base = 10;
std::string output = itoa(input, buffer, number_base);
Update
C++11 introduced several std::to_string overloads (note that it defaults to base-10).
The following macro is not quite as compact as a single-use ostringstream or boost::lexical_cast.
But if you need conversion-to-string repeatedly in your code, this macro is more elegant in use than directly handling stringstreams or explicit casting every time.
It is also very versatile, as it converts everything supported by operator<<(), even in combination.
Definition:
#include <sstream>
#define SSTR( x ) dynamic_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
Explanation:
The std::dec is a side-effect-free way to make the anonymous ostringstream into a generic ostream so operator<<() function lookup works correctly for all types. (You get into trouble otherwise if the first argument is a pointer type.)
The dynamic_cast returns the type back to ostringstream so you can call str() on it.
Use:
#include <string>
int main()
{
int i = 42;
std::string s1 = SSTR( i );
int x = 23;
std::string s2 = SSTR( "i: " << i << ", x: " << x );
return 0;
}
You can use this function to convert int to std::string after including <sstream>:
#include <sstream>
string IntToString (int a)
{
stringstream temp;
temp<<a;
return temp.str();
}
You might include the implementation of itoa in your project.
Here's itoa modified to work with std::string: http://www.strudel.org.uk/itoa/
Suppose I have integer = 0123456789101112. Now, this integer can be converted into a string by the stringstream class.
Here is the code in C++:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,i;
string s;
stringstream st;
for(i=0;i<=12;i++)
{
st<<i;
}
s=st.str();
cout<<s<<endl;
return 0;
}
#include <string>
#include <stdlib.h>
Here, is another easy way to convert int to string
int n = random(65,90);
std::string str1=(__String::createWithFormat("%c",n)->getCString());
you may visit this link for more methods
https://www.geeksforgeeks.org/what-is-the-best-way-in-c-to-convert-a-number-to-a-string/