How to exit the loop :while(cin>>n) in C++ - c++

This is a program that counts how many letters and numbers a string has,but when I Press Enter to exit after entering,it has no response.
#include <iostream>
using namespace std;
int main()
{
char c;
int nums=0,chars=0;
while(cin>>c){
if(c>='0'&&c<='9'){
nums++;
}else if((c>='A'&&c<='Z')||(c>='a'&&c<='z')){
chars++;
}
}
printf("nums:%d\nchars:%d",nums,chars);
return 0;
}

Pressing enter does not end input from std::cin and std::cin stops when encountering a whitespace.
Better would be to use std::getline and std::isdigit as shown below:
int main()
{
int nums=0,chars=0;
std::string input;
//take input from user
std::getline(std::cin, input);
for(const char&c: input){
if(std::isdigit(static_cast<unsigned char>(c))){
nums++;
}
else if(std::isalpha(static_cast<unsigned char>(c))){
chars++;
}
}
std::cout<<"nums: "<<nums<<" chars: "<<chars;
return 0;
}
Demo

Related

Get user input with multple values formated with comma

I want to achive someting like this:
User input values here for example 1,2,3
Your values: 1,2,3 [1,2,3 is inputed by user in one line]
and this values are pushed to array.I need check here if number is not bigger than max number for example 4 and isnt below 1.
I came up with this code. It takes msg to show for user and max num,but as you can see it only can return single value and i have no idea how to modify it to work as i discribed it.
const int getMultipleIntAboveZero(const std::string &msg,int maxNum){
int num;
std::cout<< msg;
while(!(std::cin>>num)|| num < 1 || num > maxNum){
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout<<"\nInvalid input. Try again: ";
}
return num;
}
How can I get integer array inputted by user with commas?
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
std::vector< int > getMultipleIntAboveZero(std::string msg, int maxNum) {
std::istringstream iss (msg);
std::string unit;
std::vector<int> nums;
int num;
while(std::getline(iss, unit, ',')) {
num = std::stoi(unit);
if (num >= 1 && num <= maxNum) {
std::cout << num << '\n';
nums.push_back(num);
} else {
std::cout<<"Invalid input. Try again\n";
}
}
return nums;
}
int main()
{
printf("Your values: ");
std::string msg;
std::cin >> msg;
getMultipleIntAboveZero(msg, 4);
}

Why does this not ask user for another input?

This part of a larger project. Right now it's supposed to ask user for a string, calculate how many words are in it, print out the # of words, ask user if they want to do it again, then if they want to, ask for another string, and so on. But this only works fine the first time. After that, it takes the answer to the yes/no question as the test string. For example: I like coding. 3. Again? Yes/no. Yes. 1. Again? Yes/no... Can someone tell me how to fix this glitch?
#include <iostream>
#include <string>
using namespace std;
string original[10] = { "hello", "sir", "madam", "officer", "stranger", "where", "is", "the", "my", "your" };
string translated[10] = { "ahoy", "matey", "proud beauty", "foul blaggart", "scurvy dog", "whar", "be", "th'", "me", "yer" };
string input;
string ans;
bool playAgain()
{
cout << "Another? yes/no: ";
cin >> ans;
if (ans.compare("yes") == 0) { return true; }
if (ans.compare("no") == 0) { return false; }
}
int getNumOfWords(string input)
{
int numOfSpaces = 0;
string current;
for (int i = 0; i < input.length(); i++)
{
current = input.at(i);
if (current.compare(" ") == 0)
{
numOfSpaces++;
}
}
return numOfSpaces + 1;
}
void play(string input)
{
int numOfWords = getNumOfWords(input);
cout << numOfWords << endl;
}
void start()
{
getline(cin, input);
play(input);
}
int main()
{
bool playing;
do
{
start();
playing = playAgain();
} while (playing);
return 0;
}
When cin.getline() reads from the input, there is a newline character left in the input stream, so it doesn't read your c-string. Use cin.ignore() beore calling getline()
void start()
{ cin.ignore();
getline(cin, input);
play(input);
}
It's because of the difference between getline and cout. The former reads in the entire line up to and including the terminating \n, while cout will read only up to the \n or whitespace. The cin in your code reads in yes or no to ans (try printing it out immediately afterwards), but it doesn't account for the \n. Thus, when you call getline it finds the \n waiting in stdin, and so reads that into input instead of blocking until cin wasn't empty.

C++ cin.getline() causes program to crash

I'm making a simple encryption/decryption program... I'm a beginner.
#include <time.h>
#include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;
char s[1025];
char o[1025];
char key[1025];
char tochar(int a)
{
if(a<26) return 'a'+a;
if(a>25 and a<52) return 'A'+a-26;
if(a>51) return '0'+a-52;
}
int toint(char t)
{
if(t>='a' and t<='z') return 0-'a'+t;
if(t>='A' and t<='Z') return 26+t-'A';
if(t>='0' and t<='9') return 52+t-'0';
}
int main()
{
int i,j,keylenght;
//for(j=0;j<62;j++)cout<<j<<" "<<tochar(j)<<" "<<toint(tochar(j))<<endl;
cout<<"Enter String:\n";
cin.getline(s,1024);
cout<<"Function [encrypt/decrypt]: ";
char f;
cin>>f;
if(f=='e')
{
cout<<"Generate key? [y/n]: ";
cin>>f;
if(f=='y')
{
cout<<"Enter key length [up to 1024]: ";
cin>>keylenght;
srand(time(0));
for(i=0;i<keylenght;i++)
{
key[i]=tochar(rand()%62);
}
}
else
{
cout<<"Enter key: \n";
cin.getline(key,1024);
for(keylenght=0;key[keylenght]!='\0';keylenght++);
}
for(i=0;s[i]!='\0';i++)
{
if(key[keylenght%i]!=' ')
{
if(s[i]!=' ')o[i]=tochar((toint(s[i])+toint(key[i%keylenght]))%62);
else o[i]=' ';
}
else
{
o[i]=s[i];
}
}
cout<<endl<<"Encrypted string: "<<o<<endl<<"Generated key: "<<key;
}
else
{
cout<<"Enter key: ";
cin>>key;
for(keylenght=0;key[keylenght]!='\0';keylenght++);
for(i=0;s[i]!='\0';i++)
{
if(s[i]!=' ')
{
if(key) o[i]=tochar((62+toint(s[i])-toint(key[i%keylenght]))%62);
}
else o[i]=' ';
}
cout<<endl<<"Decrypted string:\n"<<o;
}
return 0;
}
The first time I use getline() it works flawlessly. However when I try to use it to write in the key[] string, it crashes the program.
Can anyone tell me what's going on?
The problem is that you are mixing your input types. When you call
cin>>f;
That leaves a newline in the input buffer. Then on your call to getline() key only gets the newline. What you need to do is clear the input buffer before you call getline. I like to use:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
Do not use istream::getline(), use std::getline() instead. It is safer.

program evaluating occurrences of repeated words

#include <iostream>
#include <vector>
#include <cstring>
#include <fstream>
#include <string>
#include <cmath>
using namespace std;
vector<string> Letter;
float frequency1(string word)
{
float count=0.0;
for (int i=0;i<Letter.size();++i)
{
transform(word.begin(),word.end(),word.begin(),::tolower);
transform(Letter[i].begin(),Letter[i].end(),Letter[i].begin(),::tolower);
if (strcmp(word.c_str(),Letter[i].c_str())==0)
{
count+=1;
}
}
count=(count/Letter.size())*100;
if (count>=0.5)
{
return count;
}
else
{
return 0.0;
}
}
int main()
{
ifstream fin;
fin.open("frequent.txt");
if (fin.fail())
{
cout<<"Error opening file!"<<endl;
}
while(!fin.eof())
{
string buffer;
getline(fin,buffer,' ');
cout<<buffer<<endl;
Letter.push_back(buffer);
}
cout<<endl;
vector<string> frequent;
vector<float> frequency;
for (int i=0;i<Letter.size();++i)
{
string a=Letter[i];
int k=0;
for (int j=0;j<i;++j)
{
transform(a.begin(),a.end(),a.begin(),::tolower);
transform(Letter[j].begin(),Letter[j].end(),Letter[j].begin(),::tolower);
if (a==Letter[j])
{
break;
}
k++;
}
int size=Letter.size();
if (k!=size-1)
{
continue;
}
float counter=frequency1(a);
if(counter>0.0)
{
frequent.push_back(Letter[i]);
frequency.push_back(counter);
}
}
cout<<"Here are the repeated words"<<endl;
for (int i=0;i<frequency.size();++i)
{
cout<<" "<<frequent[i]<<", frequency: "<<frequency[i]<<endl;
}
system("PAUSE");
return 0;
}
I am writing a program which determines the frequency of the repeated words in a document(text). If frequency is greater or equal to 0.5, the word passes as a repeated words. but when I run it, it doesn't show me any repeated word although I even calculated manually and know that there are repeated words in the document. I can't figure out the problem.
First, you should exit or wrap the remainder of main into an else, when you cannot open your input file
if (fin.fail())
{
cout<<"Error opening file!"<<endl;
}
Otherwise, you'd go on and try to read from an invalid stream.
You read your words with std::getline and a blank ' ' as delimiter. This means, that you include newlines '\n', tabs '\t', etc. in your words, which might not be what you intended. A better, and safer, approach to read your words, would be
std::string word;
while (fin >> word) {
// process word
}
This skips all whitespace and detects EOF properly as an added benefit.
There might be further problems as well.

Break a loop when the user just input an enter in visual c++ or code blocks

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.