Let's say I have a string array with 5 words and I want to only output the first 3 letters of each word. How do I go upon doing this? I know how to do it with one string but with an array of strings I get lost.
This is how to do it with one string
std::string test = "hello";
std::cout << test << std::endl;
test = test.substr(0,3);
std::cout << test << std::endl;
What I want to do is this
std::string test[5] = {"hello", "pumpkin", "friday", "snowboard", "snacks"};
I want to cout the first 3 letters of each word. I tried test[5] = test[5].substr(0,3); and that did not work.
test[5] doesn't work because you only have 5 items in your array, only indexes 0 to 4 are valid.
Generally with arrays you need to write a loop to go through each array item in turn, for instance
for (int i = 0; i < 5; ++i)
test[i] = test[i].substr(0,3);
for (int i = 0; i < 5; ++i)
cout << test[i] << endl;
With test[5] you are reading out of bounds thus invoking undefined behavior. Arrays in C++ are zero indexed so the last element would be test[4]. Create a function that utilizes for example the std::next function or string's substr member function. Call inside a range based loop:
#include <iostream>
#include <string>
void foo(const std::string& s) {
if (s.size() >= 3) {
std::cout << std::string(s.begin(), std::next(s.begin(), 3)) << '\n';
// or simply:
std::cout << s.substr(0, 3) << '\n';
}
}
int main() {
std::string test[5] = { "hello", "pumpkin", "friday", "snowboard", "snacks" };
for (const auto& el : test) {
foo(el);
}
}
test[5] = test[5].substr(0,3); won't work and more over you don't have `test[5]`, index starts from `0`.
you may want to do like this
for(int i=0 ; i<5; i++) {
test[i] = test[i].substr(0,3);
cout << test[i] << endl;
}
substr is what you are looking for. Here is my implementation.
#include <array>
#include <string>
#include <iostream>
int main () {
std::array<std::string,5> list {"hello", "pumpkin", "friday", "snowboard", "snacks"};
for (const auto &word : list){
std::cout << word << std::endl;
}
for (auto &word : list){
word = word.substr(0,3);
}
for (const auto &word : list){
std::cout << word << std::endl;
}
}
Use the standard library.
std::for_each(std::begin(test), std::end(test), [] (auto& s) { s.erase(3); });
Or even a simple range-based for loop:
for (auto&& s : test) {
s.erase(3); // Erase from index 3 to end of string.
}
Or maybe even create another container with views of the original strings:
auto test2 = std::accumulate(std::begin(test), std::end(test),
std::vector<std::string_view>{},
[] (auto& prev, std::string_view sv) -> decltype(prev)& {
prev.push_back(sv.substr(0, 3));
return prev;
});
Related
I've almost finished this task but have a little trouble in result. Here's the problem description:
Given a vector of strings, please implement the following 2 functions to process and output it:
process(): remove strings that contain digits and convert others in upper case
output(): print the strings and separate them with comma.
Hints:
If possible, manipulate the vector elements in place to avoid copying vector.
It is encouraged to leverage STL functions/algorithms.
Expected Output:
==========================================
Before: abc, 123, 456, xyz
After: ABC, XYZ
But my code caused the input is not as expected
before process: abc, 123, 456, xyz,
after process: ABC, XYZ,
Please tell me how to remove the comma in the end of string in both case before/after process
Here's my code:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <vector>
void process(std::vector<std::string>& v)
{
// Remove strings that contain digits
for(std::string &s : v)
s.erase(std::remove_if(std::begin(s), std::end(s),
[](unsigned char ch) { return std::isdigit(ch); }),
s.end());
// Convert other characters into upper case
// std::toupper has several overloads
// template <class charT> charT toupper(charT, const locale&)
// int toupper(int ch)
// So taking its address might be complicated.
// We can use lambda to let compiler found the right overload:
// (In addition, as char might be signed or not, and toupper expects unsigned char value (or EOF))
for(std::string &s : v)
{
std::transform(s.begin(), s.end(), s.begin(),
[](unsigned char c){ return std::toupper(c); });
}
std::cout << '\n';
}
void output(std::vector<std::string>& v)
{
for(std::string &str : v)
if(str != "\0")
std::cout << str << ", ";
}
int main()
{
std::vector<std::string> v = { "abc", "123", "456", "xyz" };
std::cout << "Before: "; output(v);
process(v);
std::cout << "After: "; output(v);
return 0;
}
Print first element of your vector. Make comma be printed with next elements.
void output(const std::vector<std::string> &v) {
// find 1st not-empty string
auto iter = std::find_if(v.cbegin(), v.cend(),
[](const auto &s) { return !s.empty(); });
if (iter == v.cend()) {
return; // return if all of v are empty strings
}
std::cout << *iter; // print 1st one
++iter;
// print comma and next string if not empty
for (; iter != v.cend(); ++iter) {
if (!iter->empty()) {
std::cout << ", " << *iter;
}
}
std::cout << '\n';
}
Sometimes, good old syntax is a good thing.
void output(std::vector<std::string>& v) {
// clean array
size_t n = v.size();
while(n--) if(v[n] == '\0') v.erase(v.begin() + n);
// print words
for(size_t i = 0; i < v.size(); ++i) {
std::cout << v[i];
if(i < (v.size() - 1) std::cout << ", ";
}
}
another method
void output(std::vector<std::string>& v) {
// clean array
size_t n = v.size();
while(n--) if(v[n] == '\0') v.erase(v.begin() + n);
// print words
size_t max = v.size() - 1;
for(size_t i = 0; i < max; ++i)
std::cout << v[i] << ", ";
std::cout << v[max];
}
Basically, I have to show each word with their count but repeated words show up again in my program.
How do I remove them by using loops or should I use 2d arrays to store both the word and count?
#include <iostream>
#include <stdio.h>
#include <iomanip>
#include <cstring>
#include <conio.h>
#include <time.h>
using namespace std;
char* getstring();
void xyz(char*);
void tokenizing(char*);
int main()
{
char* pa = getstring();
xyz(pa);
tokenizing(pa);
_getch();
}
char* getstring()
{
static char pa[100];
cout << "Enter a paragraph: " << endl;
cin.getline(pa, 1000, '#');
return pa;
}
void xyz(char* pa)
{
cout << pa << endl;
}
void tokenizing(char* pa)
{
char sepa[] = " ,.\n\t";
char* token;
char* nexttoken;
int size = strlen(pa);
token = strtok_s(pa, sepa, &nexttoken);
while (token != NULL) {
int wordcount = 0;
if (token != NULL) {
int sizex = strlen(token);
//char** fin;
int j;
for (int i = 0; i <= size; i++) {
for (j = 0; j < sizex; j++) {
if (pa[i + j] != token[j]) {
break;
}
}
if (j == sizex) {
wordcount++;
}
}
//for (int w = 0; w < size; w++)
//fin[w] = token;
//cout << fin[w];
cout << token;
cout << " " << wordcount << "\n";
}
token = strtok_s(NULL, sepa, &nexttoken);
}
}
This is the output I get:
I want to show, for example, the word "i" once with its count of 5, and then not show it again.
First of all, since you are using c++, I would recommend you to split text in c++ way(some examples are here), and store every word in map or unordered_map. Example of my realization you can find here
But if you don't want to rewrite your code, you can simply add a variable that will indicate whether a copy of the word was found before or after the word position. If a copy was not found in front, then print your word
This post gives an example to save each word from your 'strtok' function into a vector of string. Then, use string.compare to have each word compared with word[0]. Those indexes match with word[0] are marked in an int array 'used'. The count of match equals to the number marks in the array used ('nused'). Those words of marked are then removed from the vector, and the remaining carries on to the next comparing process. The program ends when no word remained.
You may write a word comparing function to replace 'str.compare(str2)', if you prefer not to use std::vector and std::string.
#include <iostream>
#include <string>
#include <vector>
#include<iomanip>
#include<cstring>
using namespace std;
char* getstring();
void xyz(char*);
void tokenizing(char*);
int main()
{
char* pa = getstring();
xyz(pa);
tokenizing(pa);
}
char* getstring()
{
static char pa[100] = "this is a test and is a test and is test.";
return pa;
}
void xyz(char* pa)
{
cout << pa << endl;
}
void tokenizing(char* pa)
{
char sepa[] = " ,.\n\t";
char* token;
char* nexttoken;
std::vector<std::string> word;
int used[64];
std::string tok;
int nword = 0, nsize, nused;
int size = strlen(pa);
token = strtok_s(pa, sepa, &nexttoken);
while (token)
{
word.push_back(token);
++nword;
token = strtok_s(NULL, sepa, &nexttoken);
}
for (int i = 0; i<nword; i++) std::cout << word[i] << std::endl;
std::cout << "total " << nword << " words.\n" << std::endl;
nsize = nword;
while (nsize > 0)
{
nused = 0;
tok = word[0] ;
used[nused++] = 0;
for (int i=1; i<nsize; i++)
{
if ( tok.compare(word[i]) == 0 )
{
used[nused++] = i; }
}
std::cout << tok << " : " << nused << std::endl;
for (int i=nused-1; i>=0; --i)
{
for (int j=used[i]; j<(nsize+i-nused); j++) word[j] = word[j+1];
}
nsize -= nused;
}
}
Notice that the removal of used words has to do in backward order. If you do it in sequential order, the marked indexes in the 'used' array will need to be changed. A running test:
$ ./a.out
this is a test and is a test and is test.
this
is
a
test
and
is
a
test
and
is
test
total 11 words.
this : 1
is : 3
a : 2
test : 3
and : 2
I read your last comment.
But I am very sorry, I do not know C. So, I will answer in C++.
But anyway, I will answer with the C++ standard approach. That is usually only 10 lines of code . . .
#include <iostream>
#include <algorithm>
#include <map>
#include <string>
#include <regex>
// Regex Helpers
// Regex to find a word
static const std::regex reWord{ R"(\w+)" };
// Result of search for one word in the string
static std::smatch smWord;
int main() {
std::cout << "\nPlease enter text: \n";
if (std::string line; std::getline(std::cin, line)) {
// Words and its appearance count
std::map<std::string, int> words{};
// Count the words
for (std::string s{ line }; std::regex_search(s, smWord, reWord); s = smWord.suffix())
words[smWord[0]]++;
// Show result
for (const auto& [word, count] : words) std::cout << word << "\t\t--> " << count << '\n';
}
return 0;
}
string a = MwZwXxZwDwJrBxHrHxMrGrJrGwHxMrFrZrZrDrKwZxLrZrFwZxErMrXxArZw;
Assume i have this data in my string . I want to record how many M , Z , X , D , J (including those capital letters i didn't mentions ) in in string how can do it ? My friends say use vector can do it but i does not really know how to use vector is there any alternative way to do it .
I tried using for loops to do and find the M , and reset the pointer to 0 to continue find the next capital value , but not sure is there any easier way to do it .
first I'll show you a 'easier' way to me.
#include <iostream>
#include <map>
using namespace std;
int main(int argc, const char * argv[]) {
string str = "MwZwXxZwDwJrBxHrHxMrGrJrGwHxMrFrZrZrDrKwZxLrZrFwZxErMrXxArZw";
map<char,int> map;
for (int i=0; i<str.length(); i++) {
char ch = str[i];
if (isupper(ch)) {
map[ch] ++;
}
}
for (auto item : map) {
cout<<item.first<<':'<<item.second<<endl;
}
return 0;
}
you'll only need to use 1 loop to solve your problem.
the 'isupper(int _c)' is a function from the standard library, it can tell you wether a character is a capital letter.
the 'map' is a data structure from the standard library too, it can do key-value storage for you.
this program outputs this:
A:1
B:1
D:2
E:1
F:2
G:2
H:3
J:2
K:1
L:1
M:4
X:2
Z:8
is this what you want?
Use regex.
using namespace std;
// regex_search example
#include <iostream>
#include <string>
#include <regex>
int main ()
{
std::string s ("MwZwXxZwDwJrBxHrHxMrGrJrGwHxMrFrZrZrDrKwZxLrZrFwZxErMrXxArZw;");
std::smatch m;
std::regex e ("[A-Z\s]+");
map<string,int> map;
std::cout << "Target sequence: " << s << std::endl;
std::cout << "Regular expression: [A-Z\s]+" << std::endl;
std::cout << "The following matches and submatches were found:" << std::endl;
while (std::regex_search (s,m,e)) {
for (auto x:m)
{
//cout << x << " ";
map[x.str()] ++;
}
//cout << std::endl;
s = m.suffix().str();
}
for (auto item : map) {
cout<<item.first<<':'<<item.second<<endl;
}
return 0;
}
The most direct translation of "loop through the string and count the uppercase letters" into C++ I can think of:
#include <iostream>
#include <map>
#include <cctype>
int main()
{
string a = "MwZwXxZwDwJrBxHrHxMrGrJrGwHxMrFrZrZrDrKwZxLrZrFwZxErMrXxArZw";
std::map<char, int> count;
// Loop through the string...
for (auto c: a)
{
// ... and count the uppercase letters.
if (std::isupper(c))
{
count[c] += 1;
}
}
// Show the result.
for (auto it: count)
{
std::cout << it.first << ": " << it.second << std::endl;
}
}
I need help for my university homework. i'm still new to this.
Basically i am doing a run-length encoding and i don't know how to add the letter after the counter:
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
void error(std::string str)
{
throw std::runtime_error(str);
}
int main()
{ int counter = 1;
std::string id;
std::vector<int> v;
std::cout << "Enter the data to be compressed: ";
std::cin >> id;
try
{ for(int i = 0; i < id.size(); i++)
{
if(std::isdigit(id[i]))
error("invalid input");
}
std::cout << "The compressed data is: ";
for(int i = 0; i < id.size(); i++)
{
if(id[i] == id[i+1])
{
counter++;
}
else if(id[i]!= id[i+1])
{
v.push_back(counter);
v.push_back(id[i]);
counter=1;
}
}
for(int j = 0; j < v.size(); j++)
std::cout << v[j];
}
catch(std::runtime_error& str)
{
std::cerr << "error: " << str.what() << std::endl;
return 1;
}
return 0;
}
For example if i input aaabbb, the probram should output 3a3b. The problem is that it outputs 397398 97 and 98 being the ascii code for a and b.
i don't know how to put the letter after the counter and for them to be in the same vector.
If you want to serialize as a string try this :
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <sstream>
void error(std::string str) {
throw std::runtime_error(str);
}
int main() {
std::ostringstream stream;
int counter = 1;
std::string id;
std::cout << "Enter the data to be compressed: ";
std::cin >> id;
try {
for (int i = 0; i < id.size(); i++) {
if (std::isdigit(id[i]))
error("invalid input");
}
std::cout << "The compressed data is: ";
for (int i = 0; i < id.size(); i++) {
if (id[i] == id[i + 1]) {
counter++;
} else if (id[i] != id[i + 1]) {
stream << counter;
stream << (char) id[i];
counter = 1;
}
}
std::cout << stream.str() << std::endl;
} catch (std::runtime_error& str) {
std::cerr << "error: " << str.what() << std::endl;
return 1;
}
}
v[j] from std::cout << v[j] is of type int and that is why std::cout writes a number. To write it as a character, you should cast v[j] to char as follows: std::cout << (char)v[j]. In this way, std::cout will use the char specialization, not the int one.
While the other answers might give you the output you need, I believe the idiomatic way to solve this is using a class to hold both the character and its count. There are two obvious choices.
std::pair
Could also be std::tuple if you prefer it for consistency or whatever reason. Save your results in a std::vector<std::pair<char, int>. This saves the information, but to print it you would need to define an appropriate function. Add elements via
v.emplace_back(character, count);
Wrapper Class
If you want to offer some functionality without outside helper classes, define a custom wrapper class such as the following.
class CharacterCount {
private:
char character;
int count;
public:
CharacterCount(char character, int count):
character(character), count(count) {}
explicit operator std::string() const { return std::to_string(count) + character;
// Other helper functions or constructors you require
}
This simplifies printing
for (auto& character_count : v)
std::cout << static_cast<std::string>(character_count);
I believe because std::ostream::operator<< is templated, you cannot get an implicit conversion to std::string to work. I would advise against implicit conversion anyway.
You can use the same emplace_back syntax as before because we offer an appropriate constructor.
So you take your input in a string and ultimately just need to stream this information out, ultimately meaning there's really no reason to store the information in a vector, just output it! You can use find_if with a lambda to find the non-consecutive character (or find_if_not if you prefer.)
for(string::const_iterator finish, start = cbegin(id); start != cend(id); start = finish) {
finish = find_if(start, cend(id), [value = *start](const auto i) { return i != value; } );
cout << distance(start, finish) << *start;
}
Live Example
I would like to make an array of words like: "Tom", "Mike","Tamara","Nik"... I would like to make for user to be possible to enter for instance a number 3, and get a random return of words that have the length of 3 so eather ("Tom" or "Nik"). I think this is done with pointers but I don't know how. Words should be stored in different arrays depending on their length. And with pointers you would point to each array ("Tom","Nik" in same array "Tamara" in different array and "Mike" in different array and so on... because their length is not the same). Can someone please help ?
#include<iostream>
#include <string>
using namespace std;
void IzpisPolja(char **polje,int velikost){
int tab[100];
for (int i=0; i<velikost; i++) {
cout<<polje[i]<<endl;
char *zacasni;
tab[i] = strlen(polje[i]);
// cout<<tab[i]<<endl;
}
}
int main(){
const int size = 4;
char* tabelaOseb[size] = {"Tom", "Mike","Tamara","Nik"};
IzpisPolja(tabelaOseb,size);
return 0;
}
Do you want to do it efficiently ? Storing them in separate arrays will increase search time but also increase insertion, deletion complexity.
Otherwise you can just count number of instances of n length words in an array, then generate random number and return the ith of them.
Also suggest using std::vector
const string* getRandNameOfLength(const string* arr,
const int arrlen,
const int length)
{
int num = 0, j, i;
// Counting number of such names
for (i = 0; i < arrlen; ++i)
{
if (arr[i].size() == length)
num++;
}
// No such name found
if (num == 0)
return NULL;
j = rand() % num;
// Returning random entry of given length
for (i = 0; i < arrlen; ++i)
{
if (arr[i].size() == length && j-- == 0)
return &arr[i];
}
// Function shouldn't get here
return NULL;
}
You can use raw pointers to perform your task, of course, but you can also start using some of the many safer facilities that the language (references, iterators and smart pointers) and the C++ standard library can offer.
I'll show you a complete program that can do what you are asking using conteiners (std::vector, std::map) and algorithms (like std::lower_bound) that can really simplify your work once understood.
Note that as a learning exercise (for both of us), I have used as many "new" features as I could, even when maybe wasn't necessary or handy. Read the comments for better understanding.
The words are stored and managed in a class, while the interaction with the user is performed in main().
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <limits>
#include <algorithm>
#include <random> // for mt19937, uniform_int_distribution
#include <chrono> // for high_resolution_clock
size_t random_index( size_t a, size_t b ) {
// Initialize Random Number Generator Engine as a static variable. - Since c++11, You can use those instead of old srand(time(NULL))
static std::mt19937 eng{static_cast<long unsigned int>(std::chrono::high_resolution_clock::now().time_since_epoch().count())};
// use the RNG to generate random numbers uniformly distributed in a range
return std::uniform_int_distribution<size_t>(a,b)(eng);
}
using svs_t = std::vector< std::string >; // I store the words with equal length in a std::vector of std::string
// like typedef, I'll use svs_t instead of std::vector<std::string>
auto string_less_then = [] (const std::string & a, const std::string & b) -> bool { return a.compare(b) < 0; };
// A lambda function is a mechanism for specifying a function object, its primary use is to specify a simple
// action to be performed by some function. I'll use it to compare two string and return true only if a<b
class word_table {
std::map< size_t, svs_t > words; // std::map store elements formed by a combination of a key value and a mapped value, sorted by key
// I'll use word's length as a key for svs_t values
public:
word_table() {}
word_table( std::initializer_list<std::string> vs ) {
insert_words(vs);
}
void insert_words( svs_t vs ) {
for ( auto && s : vs ) add_word(s); // loop for each value in vs, "auto" let the compiler infer the right type of the variable
}
bool add_word( std::string s ) { // I choose to keep the vector sorted and with unique elements
size_t sl = s.length();
if ( sl > 0 ) {
auto & v = words[sl]; // If sl doesn't match the key of any element in the map, a new element is created
// lower_bound return an iterator that poins to the first element in range (begin,end)
auto it = std::lower_bound(v.begin(), v.end(), s, string_less_then); // which does not compare less than s
// I pass the compare function as a lambda
if ( it != v.end() && it->compare(s) == 0 ) return false; // Already present, duplicates not allowed
v.insert(it, s); // Not the most efficient way, but you seem focused on the random access part
return true;
}
return false;
}
bool remove_word( std::string s) {
size_t sl = s.length();
if ( sl > 0 ) {
auto itvw = words.find(sl); // first find the right element in the map, using the string length as a key, but if word is found
if ( itvw == words.end() ) return false; // an iterator to the element following the last element of the container is returned
auto & v = itvw->second; // In a map the elements are stored in pairs, first is the key, second the value
auto it = std::lower_bound(v.begin(), v.end(), s, string_less_then);
if ( it != v.end() && it->compare(s) == 0 ) {
v.erase(it);
if ( v.empty() ) words.erase(itvw);
return true;
}
}
return false;
}
std::string get_random_word( size_t length ) {
if ( length == 0 ) return "";
auto itvw = words.find(length);
if ( itvw == words.end() || itvw->second.empty() ) return "";
return itvw->second[random_index(0, itvw->second.size() - 1)];
}
void show_all() {
for ( auto && i : words ) {
std::cout << " ";
for (auto && w : i.second ) {
std::cout << w << ' ';
}
std::cout << '\n';
}
}
};
constexpr size_t ss_max = std::numeric_limits<std::streamsize>::max();
namespace opt {
enum options { wrong = -1, exit, show, random, add, remove, menu };
}
class menu {
std::map<int,std::string> opts;
public:
menu( std::initializer_list<std::pair<int,std::string>> il ) {
for ( auto && i : il ) opts.insert(i);
}
void show() {
std::cout << "\nYou can choose among these options:\n\n";
for ( auto && i : opts ) {
std::cout << " " << i.first << ". " << i.second << ".\n";
}
}
};
int main()
{
word_table names({"Tom", "Mike","Tamara","Robert","Lenny","Nick","Alex","Sue","Irina","Beth","Anastacia","Bo"});
int choise = opt::exit;
menu menu_options { {opt::exit, "Exit program"}, {opt::show, "Show all stored names"},
{opt::random, "Show a random name"}, {opt::add, "Add a new name"},
{opt::remove, "Remove a name"} };
menu_options.show();
do {
std::cout << "\nPlease, enter a number (" << opt::menu << " to show again all options): ";
std::cin >> choise;
if ( std::cin.fail() ) { // the user enter something that is not a number
choise = opt::wrong;
std::cin.clear();
std::cin.ignore(ss_max,'\n');
}
if ( std::cin.eof() ) break; // use only if you are redirecting input from file
std::string str;
switch ( choise ) {
case opt::exit:
std::cout << "\nYou choose to quit, goodbye.\n";
break;
case opt::show:
std::cout << "\nAll the stored names, classified by word\'s length:\n\n";
names.show_all();
break;
case opt::random:
size_t l;
std::cout << "Please, enter the length of the name: ";
std::cin >> l;
if ( std::cin.good() ) {
std::string rs = names.get_random_word(l);
if ( rs == "" ) {
std::cout << "\nNo name of length " << l << " has been found.\n";
} else {
std::cout << "\n " << rs << '\n';
}
}
break;
case opt::add:
std::cout << "Please, enter the name You want to add: ";
std::cin >> str; // read a string from cin, you can write more than a word (separeted by spaces)
std::cin.ignore(ss_max,'\n'); // but only the first is stored
if ( names.add_word(str) ) {
std::cout << "\n The name " << str << " has been successfully added.\n";
} else {
std::cout << "\n No name has been added";
if ( str != "" ) std::cout << ", "<< str << " is already present.\n";
else std::cout << ".\n";
}
break;
case opt::remove:
std::cout << "Please, enter the name You want to remove: ";
std::cin >> str;
if ( names.remove_word(str) ) {
std::cout << "\n " << str << " has been succesfully removed.\n";
} else {
std::cout << "\n No name has been removed";
if ( str != "" ) std::cout << ", " << str << " wasn't found.\n";
else std::cout << ".\n";
}
break;
case opt::menu:
menu_options.show();
break;
default:
std::cout << "\n Sorry, that's not an option.\n";
}
} while ( choise != opt::exit );
return 0;
}
I hope it could help.
#include <iostream>
#include <vector>
#include <cstring>
#include <ctime>
#include <cstdlib>
using namespace std;
const char* return_rand_name(const char** names, size_t length)
{
std::vector<size_t> indexes;
for(int i=0; names[i][0] != 0; ++i)
if(strlen(names[i]) == length)
indexes.push_back(i);
if(indexes.size()==0)
return NULL;
return names[indexes[rand()%indexes.size()]];
}
int main()
{
srand(time(NULL));
const char* names[] = {"Alex","Tom","Annie","Steve","Jesus","Leo","Jerry",""};
std::cout << return_rand_name(names, 3) << std::endl;
return 0;
}
And if you want to use functions like strlen etc, include <cstring>, not <string> (which contains class template std::string (which you should use in C++ (instead of char*) ) )