I want to write a program that counts the number of times a certain vowel appears in a string but each value must be returned.
int vowel_count(string);
int main()
{
string str;
cout << "Enter a string";
cin >> str;
// Calling funtion:
vowel_count(str);
}
int vowel_count(string var)
{
int sum_a = 0;
int sum_e = 0;
int sum_i = 0;
int sum_o = 0;
int sum_u = 0;
for (int j = 0; j < var.length(); j++)
{
if (Var.at(j) == 'a')
sum_a++;
if (Var.at(j) == 'e')
sum_e++;
if (Var.at(j) == 'i')
sum_i++;
if (Var.at(j) == 'o')
sum_o++;
if (Var.at(j) == 'u')
sum_u++;
}
return sum_a;
return sum_e;
return sum_i;
return sum_o;
return sum_u;
}
Everytime I return , the program terminates, I would like to know how to I overrun the function of return.
You can use std::tuple to return multiple values from a function. Then you can either use std::get or std::tie to get at the values in the tuple. This avoids having to define a struct/class simply for the purpose of returning a result from your function vowel_count().
Since you tagged your question with C++14, I assume you haven't got C++17. However, with C++17 you can use structured bindings to extract the values instead.
For C++11/C++14:
#include<iostream>
#include<tuple>
using TupleVowel = std::tuple<int, int, int, int, int>;
TupleVowel vowel_count(std::string var)
{
int sum_a = 0;
int sum_e = 0;
int sum_i = 0;
int sum_o = 0;
int sum_u = 0;
for (int j = 0; j < var.length(); j++)
{
if (var.at(j) == 'a')
sum_a++;
if (var.at(j) == 'e')
sum_e++;
if (var.at(j) == 'i')
sum_i++;
if (var.at(j) == 'o')
sum_o++;
if (var.at(j) == 'u')
sum_u++;
}
return std::make_tuple(sum_a, sum_e, sum_i, sum_o, sum_u);
}
int main(void)
{
int sum_a = 0;
int sum_e = 0;
int sum_i = 0;
int sum_o = 0;
int sum_u = 0;
std::tie(sum_a, sum_e, sum_i, sum_o, sum_u) = vowel_count("hello world");
std::cout << "sum_a = " << sum_a << ", sum_e = " << sum_e << ", sum_i = " << sum_i << ", sum_o = " << sum_o << ", sum_u = " << sum_u << std::endl;
}
Live demo.
You can also use std::get() with the index of the element like this without having to 'tie' the tuple elements to variables:
auto tup = vowel_count("hello world");
std::cout << "sum_a = " << std::get<0>(tup) << ", sum_e = " << std::get<1>(tup) << ", sum_i = " << std::get<2>(tup) << ", sum_o = " << std::get<3>(tup) << ", sum_u = " << std::get<4>(tup) << std::endl;
In C++17, you can just do:
auto [sum_a, sum_e, sum_i, sum_o, sum_u] = vowel_count("hello world");
Live demo.
When the type of the returned variable is the same, you can use a std::array (also std::vector or std::deque, but, given that the number of the returned variable is fixed, I suppose std::array is preferable)
I mean, something as follows
#include <array>
#include <iostream>
auto vowel_count (std::string var)
{
int sum_a = 0;
int sum_e = 0;
int sum_i = 0;
int sum_o = 0;
int sum_u = 0;
for ( auto const & ch : var )
if ( ch == 'a') ++sum_a;
else if ( ch == 'e') ++sum_e;
else if ( ch == 'i') ++sum_i;
else if ( ch == 'o') ++sum_o;
else if ( ch == 'u') ++sum_u;
return std::array<int, 5u>{ sum_a, sum_e, sum_i, sum_o, sum_u };
}
int main()
{
std::string str;
std::cout << "Enter a string";
std::cin >> str;
auto vc = vowel_count(str);
std::cout << "a: " << vc[0] << std::endl;
std::cout << "e: " << vc[1] << std::endl;
std::cout << "i: " << vc[2] << std::endl;
std::cout << "o: " << vc[3] << std::endl;
std::cout << "u: " << vc[4] << std::endl;
}
Observe that, starting from C++17, you can use structured bindings, exactly as suggested from jignatius in the std::tuple based solution.
auto [sum_a, sum_e, sum_i, sum_o, sum_u] = vowel_count(str);
std::cout << "a: " << sum_a << std::endl;
std::cout << "e: " << sum_e << std::endl;
std::cout << "i: " << sum_i << std::endl;
std::cout << "o: " << sum_o << std::endl;
std::cout << "u: " << sum_u << std::endl;
The answers above are way too complicated.
The easiest solution is a simple struct.
struct VowelResult {
int a;
int e;
int i;
int o;
int u;
};
VowelResult func () {
int sumA = 0;
int sumE = 0;
int sumI = 0;
int sumO = 0;
int sumU = 0;
//your code goes here...
return {sumA,sumE,sumI,sumO,sumU}; // order matters here
// alternatively:
// VowelResult res{};
// res.a = sumA;
// res.e = sumE;
// and so on...
// return res;
// alternatively alternativey you can simply use the struct directly to store the sums
}
Related
How can I parse a const char* from a double or long?
Mainly because my code is a lot faster when I use a const char*, so i decided to create a small base string class. But my code to parse a double has some bugs.
My code only works partially. Some help would be very appreciated.
I am using macos, g++ & c++17.
Code:
#include <iostream>
class bstring {
public:
const char* characters;
bstring(const char* c = "") { characters = c; }
static bstring parse(const double number, int precision = 100) {
// Convert.
int decimal, sign;
char *buffer;
buffer = ecvt(number, precision, &decimal, &sign);
int n = strlen(buffer);
// Add decimal.
char before[decimal];
strncpy(before, 0 + buffer, decimal);
char after[n - decimal - 1];
strncpy(after, decimal + buffer, n - decimal - 1);
// Remove zero padding.
int removed = 0;
while (true) {
size_t n = sizeof(after) - removed;
size_t index_to_remove = n - 1;
if (after[index_to_remove] == '0') {
for (size_t i = index_to_remove; i < n - 1; ++i) {
after[i] = after[i + 1];
}
removed += 1;
} else { break; }
}
bool is_zero = removed == sizeof(after);
int after_size = sizeof(after)-removed;
char* nafter = (char*)malloc(sizeof(char) * after_size);
// Concat.
char* new__{ new char[strlen(before) + 1 + after_size] };
new__ = strcpy(new__, before);
new__ = strcat(new__, ".");
if (is_zero) {
char a[] = "0";
new__ = strcat(new__, a);
} else {
new__ = strcat(new__, after);
}
// Assign.
bstring s = new__;
delete[] new__; new__ = NULL;
return s;
//
}
};
std::ostream& operator <<(std::ostream &s, bstring x) { return s << x.characters; }
int main() {
std::cout << "Should be " << "-1234.39950" << ": " << bstring::parse(-1234.39950) << std::endl;
std::cout << "Should be " << "-1.0" << ": " << bstring::parse(-1.0) << std::endl;
std::cout << "Should be " <<"0.0" << ": " << bstring::parse(0.0) << std::endl;
std::cout << "Should be " <<"0.3897495" << ": " << bstring::parse(0.3897495) << std::endl;
std::cout << "Should be " <<"1.0" << ": " << bstring::parse(1.0) << std::endl;
std::cout << "Should be " <<"100.00" << ": " << bstring::parse(1000.0) << std::endl;
std::cout << "Should be " <<"10000.000" << ": " << bstring::parse(1000000.0) << std::endl;
std::cout << "Should be " <<"1000000.0000" << ": " << bstring::parse(1000000000.0) << std::endl;
std::cout << "Should be " <<"1000000000.0000" << ": " << bstring::parse(1000000000000.0) << std::endl;
std::cout << "Should be " <<"1000000000000.0000" << ": " << bstring::parse(1000000000000000.0) << std::endl;
}
Edit:
Is this piece of code okay? Or am I doing something wrong by not deleting it / By where I assign the new__ to.
// Concat.
bstring concat(const char* c) {
int n = ::strlen(characters) + ::strlen(c);
if (n == 0) { return bstring(); }
if (::strlen(c) == 0) { return bstring(characters); }
char* new__{ new char[n + 1] };
new__ = strcpy(new__, characters);
new__ = strcat(new__, c);
// const char* n = new__;
// delete[] new__; new__ = NULL;
bstring s = new__;
return s;
}
I want to display a progress bar however putting the printing code inside a separate function seems to invoke an std::flush as each time the progress bar is printing in a new line. This did not happen when the code was used inline
The code:
#include <iostream>
#include <unistd.h>
void load(int curr, int total) {
std::cout << "\n[";
int pos = 50 * curr/total;
for (int i = 0; i < 50; ++i) {
if (i < pos) std::cout << "=";
else if (i == pos) std::cout << ">";
else std::cout << " ";
}
std::cout << "]" << int(float(curr)/(float)total * 100.0) << " %\r";
std::cout.flush();
}
int main(){
for( int i = 0; i <= 5; i++ ){
load(i,5);
}
std::cout << std::endl;
return 0;
}
What it does:
[> ]0 %
[==========> ]20 %
[====================> ]40 %
[==============================> ]60 %
[========================================> ]80 %
[==================================================]100 %
What it's supposed to do: print all on the same line
The first line in your function outputs \n, which is what makes it print on a new line every iteration.
Fix:
#include <iostream>
void load(int curr, int total) {
std::cout << '[';
int pos = 50 * curr/total;
for (int i = 0; i < 50; ++i) {
if (i < pos) std::cout << '=';
else if (i == pos) std::cout << '>';
else std::cout << ' ';
}
std::cout << ']' << int(float(curr)/(float)total * 100.0) << " %\r" << std::flush;
}
int main(){
for( int i = 0; i <= 5; i++ ){
load(i, 5);
}
std::cout << '\n';
}
It is a homework problem. It compiles fine, but linker gives undefined reference to my function getSalesData - line 20 just after my first for loop. Here is the code. I cannot find where I have done anything incorrectly; I have my prototype defined and it matches my function header, and I am simply calling the function.
// chips and salsa
#include <iostream>
#include <iomanip>
#include <string>
int getJarsSold(std::string type);
void getSalesData(int jarsSold[],int size,int &totalJars,int &highSeller,int &lowSeller);
int main() {
const int SIZE = 5;
const std::string salsaTypes[] {"Mild","Medium","Sweet","Hot","Zesty"};
int jarsSold[SIZE] = {};
int highIndex,lowIndex,totalJarsSold;
for (int i = 0; i < SIZE; i++) {
jarsSold[i] = getJarsSold(salsaTypes[i]);
}
getSalesData(jarsSold,SIZE,totalJarsSold,highIndex,lowIndex);
std::cout << " Type Jars Sold\n";
std::cout << "---------------------\n";
for (int i = 0; i < SIZE; i++) {
std::cout << std::setw(8) << salsaTypes[i] << std::setw(15) << jarsSold[i] << std::endl;
}
std::cout << "*********************\n";
std::cout << "Total Sales = " << totalJarsSold << std::endl;
std::cout << "Highest Seller = " << salsaTypes[highIndex] << std::endl;
std::cout << "Lowest Seller = " << salsaTypes[lowIndex] << std::endl;
}
int getJarsSold(std::string type) {
bool validData = false;
int numJars;
while (!validData) {
std::cout << "Enter jars sold this month for " << type << " salsa type: ";
std::cin >> numJars;
if (numJars < 0) {
std::cout << "Number of jars sold must be 0 or positive number.\n";
}
else {
validData = true;
}
}
validData = false;
return numJars;
}
void getSalesData(int jarsSold[],int size,int totalJars,int highIndex,int lowIndex) {
bool firstRun = true;
int highVal,lowVal;
totalJars = 0;
for (int i = 0; i < size; i++) {
if (firstRun) {
highIndex = i;
highVal = jarsSold[highIndex];
lowIndex = i;
lowVal = jarsSold[lowIndex];
totalJars += jarsSold[i];
firstRun = false;
}
else {
totalJars += jarsSold[i];
if (jarsSold[i] > highVal) {
highVal = jarsSold[i];
highIndex = i;
}
if (jarsSold[i] < lowVal) {
lowVal = jarsSold[i];
lowIndex = i;
}
}
}
}
Any help is appreciated. I am just using -c for compiling and -o for linking, nothing fancy as I know no better.
This is a part of a program that I am writing to compute the addition of two integers as strings. (Writing my own bigInt class).
There appears to be a problem when I am adding the two integers together. Because they are both in vectors of char type, I had to add a '0' to each element of the vector before concatenating it into a string.
However, the results are still not what I am expecting:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string const Number = "1000";
string const Number2 = "1000";
vector<char> reverse;
vector<char> reverse2;
//cout << (rostrNumber[1] - '0') << endl;
cout << "Original Number: " << Number << endl;
reverse.clear();
for (int i = Number.size() - 1; i >= 0; i--)
{
reverse.push_back(Number[i]);
}
cout << "Reversed: " << endl;
cout << reverse[0] << reverse[1] << reverse[2] << reverse[3] << endl;
cout << endl << endl;
reverse2.clear();
{
for (int i = Number2.size() - 1; i >= 0; i--)
{
reverse2.push_back(Number[i]);
}
}
cout << "Adding these two integers" << endl;
vector<char> const rcvN1 = reverse;
vector<char> const rcvN2 = reverse2;
vector<char> Results;
Results.clear();
//Local copies
vector<char> vN1 = rcvN1;
vector<char> vN2 = rcvN2;
int iSize1 = vN1.size();
int iSize2 = vN2.size();
int i, iSize = iSize2;
int iC = 0, iR;
for (i = 0; i<iSize; i++)
{
iR = vN1[i] + vN2[i] + iC;
if (iR > 9)
{
iR -= 10;
iC = 1;
}
else
iC = 0;
Results.push_back(iR);
cout << Results[0] << endl;
}
if (iC > 0)
Results.push_back(iC);
string ostr;
vector<char>::const_reverse_iterator rIter = Results.rbegin();
for (; rIter != Results.rend(); rIter++)
ostr += *rIter +'0';
cout << "Results: " << ostr << endl;
system("PAUSE");
return 0;
}
I was trying to count the number of characters in a string class but for some reason the program is skipping over my function completely. This is just the test code from the main program, it still was giving me the same results. How come the counter function is skipped over?
#include <iostream>
#include <string>
using namespace std;
void prompt(string& dna)
{
cout << "Input: ";
getline(cin, dna);
}
void counter(const string DNA,
int* a_count, int* t_count, int* c_count, int* g_count)
{
for (int i = 0; i < DNA.size(); i++)
{
if (DNA.at(i) == 'a')
{
*a_count++;
}
else if (DNA.at(i) == 't')
{
*t_count++;
}
else if (DNA.at(i) == 'c')
{
*c_count++;
}
else if (DNA.at(i) == 'g')
{
*g_count++;
}
}
}
int main()
{
string dna;
int a = 0;
int t = 0;
int c = 0;
int g = 0;
prompt(dna);
if (! dna.empty())
{
cout << "Before:\n"
<< "A: " << a << endl
<< "T: " << t << endl
<< "C: " << c << endl
<< "G: " << g << endl;
counter(dna, &a, &t, &c, &g);
cout << "\n\nAfter:\n"
<< "A: " << a << endl
<< "T: " << t << endl
<< "C: " << c << endl
<< "G: " << g << endl;
}
system("pause");
return 0;
}
You're applying operator ++ the wrong way. It should be:
if (DNA.at(i) == 'a')
{
(*a_count)++;
}
else if (DNA.at(i) == 't')
{
(*t_count)++;
}
else if (DNA.at(i) == 'c')
{
(*c_count)++;
}
else if (DNA.at(i) == 'g')
{
(*g_count)++;
}
You've got a priority problem between the ++ and * operators. You are incrementing the pointer address, not the value. (*a_count)++; would be correct.
You may find it easier to use reference parameters for the counts instead, since you don't actually need to do any pointer arithetic. ie:
void counter(const string DNA, int& a_count, int& t_count, int& c_count, int& g_count)
And, yes a switch statement would be neater.