I have this code:
#include <iostream>
#include <string>
#include "header8.h"
using namespace std;
int main()
{
Counter test;
string input;
cout << "Enter a string\n";
getline(cin, input);
test.countcharacters();
test.countnumbers();
}
void Counter::countcharacters(){
for(unsigned int i=0; i<input.length(); i++){
if(input.at(i) == 'a'){
alphabet[0]++;
}
}
}
void Counter::countnumbers(){
for(unsigned int i;i<input.length();i++){
if(input.at(i) == '0'){
numbers[i]++;
}
}
}
My error:
When I enter my string, the value always returns 0. Any idea why?
Post your Counter class definition
As one of the comments correctly stated, I can see no way counter sees the same input var.
Edit: then based on your code the fix should be
replace in main
getline(cin, input);
with
getline(cin, test.input);
and remove
string input;
Here is my solution.
int main()
{
string input;
cout << "Enter a string\n";
getline(cin, input);
Counter test(input); // highlight
test.countcharacters();
test.countnumbers();
}
You need to call the constructor of class Counter and transfer 'input' to Counter::input (of course, you need to add a constructor with a string as the parameter). Or you can write a function as below:
void Counter::setInput(string _input)
{
this.input = _input;
}
and call this function before you start counting.
Related
This is a simple function which will take value from user and if value is invalid then the function will call itself recursively until a valid input is provided.
#include<iostream>
using namespace std;
void getnum(){
int num;
string strnum;
getline(cin, strnum);
try{
num = stoi(strnum);
}
catch(invalid_argument &ia){
cout<<"Invalid argument\n";
getnum();
}
cout<<"\n"<<num;
}
int main(){
getnum();
return 0;
}
/*output(input: abc,abc,abc,4):
4
2494464
2494464
4201200
*/
Using the recursive approach the program is creating a new instance of the function every time an invalid argument is passed. After receiving a valid argument, function is printing multiple values(garbage values) of num due to multiple instances created.
The problem is that I want only the last value(correct one) to be printed. So I tried setting a 'flag' to control the execution of cout<<"\n"<<num.
#include<iostream>
using namespace std;
void getnum(){
int flag = 0;
int num;
string strnum;
getline(cin, strnum);
try{
flag = 1;
num = stoi(strnum);
}
catch(invalid_argument &ia){
flag = 0;
cout<<"Invalid argument\n";
getnum();
}
if(flag)
cout<<"\n"<<num;
}
int main(){
getnum();
return 0;
}
/*output(input:abc,abc,abc,4)
4 */
It solves my problem but still multiple instances are being created which I think is wastage of memory.
Is there any better way to do this without using a lot of memory(recursion)?
You get multiple outputs because you print outside "the happy path" - move printing inside the try block.
It's even clearer to put the entire "happy path" inside the try:
void getnum(){
try {
string strnum;
getline(cin, strnum);
int num = stoi(strnum);
cout<<"\n"<<num;
}
catch(invalid_argument &ia){
cout<<"Invalid argument\n";
getnum();
}
}
The idiomatic solution is to loop rather than recurse:
void getnum(){
while (true)
{
try {
string strnum;
getline(cin, strnum);
int num = stoi(strnum);
cout << "\n" << num;
return;
}
catch (invalid_argument &){
cout<<"Invalid argument\n";
}
}
}
hi guys so my question is how to convert a char array to a string. here is my code:
#include<iostream>
using namespace std;
int main()
{
while (true) {
char lol[128];
cout << "you say >> ";
cin.getline(lol,256);
cout << lol << endl;;
}
return 0;
}
so I want to convert lol to a string variable like "stringedChar" (if thats even english lol)
so I can do stuff like:
string badwords[2] = {"frick","stupid"};
for (int counter = 0; counter < 2;counter++) {
if(strigedChar == badwords[counter]) {
bool isKicked = true;
cout << "Inappropriate message!\n";
}
}
Sorry im just a c++ begginer lol
Do something like this :
as char lol[128];
into string like: std::string str(lol);
Line : cin.getline(lol,256); <--> should be changed to cin.getline(lol,128)
Just invoke std::getline() on a std::string object instead of messing about with a char array, and use std::set<std::string> for badwords as testing set membership is trivial:
#include <iostream>
#include <set>
#include <string>
static std::set<std::string> badwords{
"frick",
"stupid"
};
int main() {
std::string line;
while (std::getline(std::cin, line)) {
if (badwords.count(line) != 0) {
std::cout << "Inappropriate message!\n";
}
}
return 0;
}
Note that this tests whether the entire line is equal to any element of the set, not that the line contains any element of the set, but your code appears to be attempting to do the former anyway.
First off, you have a mistake in your code. You are allocating an array of 128 chars, but you are telling cin.getline() that you allocated 256 chars. So you have a buffer overflow waiting to happen.
That said, std::string has constructors that accept char[] data as input, eg:
#include <iostream>
using namespace std;
int main()
{
while (true) {
char lol[128];
cout << "you say >> ";
cin.getline(lol, 128);
string s(lol, cin.gcount());
cout << s << endl;;
}
return 0;
}
However, you really should use std::getline() instead, which populates a std::string instead of a char[]:
#include <iostream>
#include <string>
using namespace std;
int main()
{
while (true) {
string lol;
cout << "you say >> ";
getline(cin, lol);
cout << lol << endl;;
}
return 0;
}
I am trying to this function to return without numbers, spaces, or other characters and I am supposed to use the .erase function. I understand that my loop keeps going out of range, but I have no clue how to fix it and I've been stuck on this for a while. If the user types "dogs are a lot of fun" and I need the function to return and output "dogsarealotoffun" Thanks for the help.
#include <iostream>
#include <cctype>
#include <cstring>
using namespace std;
//function to output string without spaces, numbers, or punctuations
string alphabetOnly (string input){
int size;
int i= 0;
size = (int)input.size();
while (input[i] < size){
if (isalpha(input[i])){
i++;
}
else
input.erase(input[i]);
}
return input;
}
int main() {
string input;
cout << "Enter a string to test: ";
getline(cin, input);
cout << "alphabetOnly: " << alphabetOnly(input) << endl;
}
EDITED: I was too hasty in my previous answer (as I am learning I need to speak from tested code rather than off the top of my head) and needed to debug. The problem is in the else case you need to erase the char, NOT increment i because the length of the string just changed, and also since the length of the string changed you need to reset size to be the new length. Sorry for the hasty answer earlier, I was speaking without actually using the compiled code.
#include <iostream>
#include <cctype>
#include <string>
//function to output string without spaces, numbers, or punctuations
std::string alphabetOnly (std::string input){
int size;
int i= 0;
size = (int)input.size();
while (i < size){
if (isalpha(input[i])){
i++;
}
else{
input.erase(i,1);
//do not increment i here since the index changed becauase of erase
size = (int)input.size();
}
}
return input;
}
int main() {
std::string input;
std::cout << "Enter a string to test: ";
std::getline(std::cin, input);
std::cout << input;
std::cout << "alphabetOnly: " << alphabetOnly(input) << std::endl;
return 0;
}
something like this:
#include <iostream>
#include <string>
#include <algorithm>
//function to output string without spaces, numbers, or punctuations
std::string alphabetOnly (std::string input)
{
auto not_alpha = [](char c) { return !std::isalpha(c); };
input.erase(std::remove_if(begin(input),
end(input),
not_alpha),
std::end(input));
return input;
}
int main() {
std::string input;
std::cout << "Enter a string to test: ";
getline(std::cin, input);
std::cout << "alphabetOnly: " << alphabetOnly(input) << std::endl;
}
http://coliru.stacked-crooked.com/a/340465d41ecd8c8e
There's quite a few things wrong with your code, but to start with here's your main error corrected.
#include <iostream>
#include <cctype>
#include <cstring>
using namespace std;
//function to output string without spaces, numbers, or punctuations
string alphabetOnly (string input){
int size;
int i= 0;
size = (int)input.size();
while (i < size){
if(isalpha(input[i]))
{
i++;
}
else
input.erase(input.begin( ) + i );
}
return input;
}
int main() {
string input;
cout << "Enter a string to test: ";
getline(cin, input);
cout << "alphabetOnly: " << alphabetOnly(input) << endl;
}
But this is awfully inefficient because you swhift all the remaining unchecked characters each time you delete.
You should use something like
input.erase( remove_if( input.begin(), input.end(), not( isalpha ) ), input.end( ));
This is known as the remove-erase idiom, whihc you can lookup anywhere.
I want to declare two types of variables in for's init-statement. like the following codes. I know "for (string word, int numb, ; cin>>word>>numb; )" is not working. just trying to let you know what I am trying to do. My goal is to declare two types of variables with the same lifetime and cin them together. Other way of coding is helpful too. thanks in advance.
#include <iostream>
#include <vector>
#include <string>
#include <utility>
using namespace std;
int main ()
{
cout<<"enter a word and a number"<<endl;
for (string word, int numb, ; cin>>word>>numb; )
{
//do some work
}
return 0;
}
ok, I think this is the closest I can get as someone suggested.
#include <iostream>
#include <vector>
#include <string>
#include <utility>
using namespace std;
int main ()
{
vector<pair<string,int> > pvec;
cout<<"enter a word and a number"<<endl;
{
int numb=0;
for (string word; cin>>word>>numb; )
pvec.push_back(make_pair(word,numb));
}
cout<<pvec[3].second<<endl;
return 0;
}
About the nearest you can get is:
int main ()
{
cout<<"enter a word and a number"<<endl;
{
string word;
for (int numb; cin>>word>>numb; )
{
//do some work
}
}
return 0;
}
The extra set of braces limits the scope of word similarly to the way the loop limits the scope of numb. Clearly, you could reverse the declarations; it might be better (more symmetric) to use:
int main ()
{
cout<<"enter a word and a number"<<endl;
{
string word;
int numb;
while (cin>>word>>numb)
{
//do some work
}
}
return 0;
}
Since there is no increment or initialize operation, the code is really a while loop with a couple of declared variables; this achieves the same result and works.
This is not possible. You can declare two variables of the same basic type in the initialization statement in the for loop, but you cannot declare two variables of different basic types. You have to declare one outside of the for loop.
I'm fairly certain it's not possible to declare 2 variables of 2 different types in a for statement, but I also fail to see the advantage to doing so over something like this:
int main ()
{
cout<<"enter a word and a number"<<endl;
while( cin.good() )
{
string word;
int num;
cin >> word >> num;
//do some work
}
return 0;
}
In general I prefer to use for loops where there is something to count or at least iterate over. Other situations should be using a while or do loop.
The way you are trying to do it is not the cleanest way. I'd do it like this:
string word;
int num;
while(true)
{
cin >> word >> num;
if (!cin.good()) break;
// do some work
}
word and num are in the same scope (same "lifetime")
Note that you'd want to substitute the while(true) with some suitable condition.
If you want word and num to be inside the scope of the loop do something like:
while(true)
{
string word;
int num;
cin >> word >> num;
if (!cin.good()) break;
// do some work
}
OR
{
string word;
int num;
while(true)
{
cin >> word >> num;
if (!cin.good()) break;
// do some work
}
}
I don't know why this would be necessary though.
The following is untested, but should work:
int main()
{
std::cout << "enter a word and a number" << endl;
for (struct { std::string word, int number } vars;
std::cin >> vars.word >> vars.number;
)
{
//do some work
}
return 0;
}
Since c++17:
#include <iostream>
#include <tuple>
int main() {
for (auto && [w,i] = std::tuple{std::string{},int{}} ; std::cin >> w >> i ; )
std::cout << "word " << w << " number " << i << "\n";
return 0;
}
I want to know how to make stop a while loop when the user just input an Enter without asking to continue or , here is my code:
int main()
{
bool flag = true;
int userInput;
while(flag){
cout<<"Give an Integer: ";
if(!(cin >> userInput) ){ flag = false; break;}
foo(userInput);
}
}
Thanks in advance.
Try this:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
int userInput;
string strInput;
while(true){
cout<<"Give an Integer: ";
getline(cin, strInput);
if (strInput.empty())
{
break;
}
istringstream myStream(strInput);
if (!(myStream>>userInput))
{
continue; // conversion error
}
foo(userInput);
}
return 0;
}
Use getline. Break if the string is empty. Then convert the string to an int.
for(std::string line;;)
{
std::cout << "Give an Integer: ";
std::getline(std::cin, line);
if (line.empty())
break;
int userInput = std::stoi(line);
foo(userInput);
}
std::stoi will throw an exception on failure, handle that however you want.