I need to count the number of an input character there is in an input sentence. I am so close however I keep getting this error:
countchar.cpp:19:19: error: empty character constant
countchar.cpp: In function â:
countchar.cpp:26:75: error: could not convert â from â to â
#include <string>
#include <fstream>
#include <iostream>
#include <algorithm>
using namespace std;
void WordOccurenceCount(string, int);
int main()
{
char character;
string sentence;
char answer;
string cCount;
while(1) {
cout << "Enter a char to find out how many times it is in a sentence: ";
cin >> character;
cout << "Enter a sentence and to search for a specified character: ";
cin >> sentence;
if(character == '' || sentence == "" )
{
cout << "Please enter a valid answer:\n";
break;
}
else {
cCount = WordOccurenceCount(sentence.begin(), sentence.end(), character);
cout << "Your sentence had" << cCount << character
<< "character(s)";
}
cout << "Do you wish to enter another sentence (y/n)?: ";
cin >> answer;
if (answer == 'n'){
break;
}
}
return 0;
}
int WordOccurrenceCount( string const & str, string const & word )
{
int count;
string::size_type word_pos( 0 );
while ( word_pos!=string::npos )
{
word_pos = str.find(word, word_pos );
if ( word_pos != string::npos )
{
++count;
// start next search after this word
word_pos += word.length();
}
}
return count;
Can anyone lend a hand?
There's no such thing as an empty character.
Just write
if (sentence == "")
{
cout << "Please enter a valid answer:\n";
break;
}
Problems with this code:
1. C++ does not take empty chars : if(character == '')
2. The arguments from your function WordOccurrenceCount do not match your declaration.
3. sentence.begin() is of String_iterator type, cannot be converted to string. (As expected by your WordOccurrenceCount function)
4. Again, sentence.end is also of String_iterator type, cannot be converted to int (As expected by your function declaration) or string (as expected by your function definition).
After counting (please mark erroneous lines somehow in the future) one of the problems was this line:
if(character == '' || sentence == "" )
In C++ (and C) you can't have empty character literals.
When you read the character and nothing is entered you get the newline, so the first check should be character == '\n'.
As for the string, there is a very simple method of checking if a string is empty: std::string::empty:
sentence.empty()
So the complete condition should be
if (character == '\n' || sentence.empty()) { ... }
As for the other errors, there are really multiple errors: To start with you declare WordOccurenceCount to take two arguments, a string and an integer. You then call it with three arguments, none of which are of the correct type.
Then in the definition of WordOccurenceCount you have different arguments compared to the declaration.
Finally, if you want to count the number of time a certain character is in a string, then you might want to look at the standard algorithms available in C++, especially std::count:
std::string sentence;
std::cout << "Enter a sentence: ";
std::getline(std::cin, sentence);
char character;
std::cout << "Enter a character to be found: ";
std::cin >> character;
long count = std::count(std::begin(sentence), std::end(sentence), character);
Related
I need to make a program which converts all letters to uppercase.
But first I need to get an input from the user. And I need to check if there are characters that are not space or alphabet.
This is what I tried.
#include <iostream>
#include <cctype>
using namespace std;
int main()
{
string s;
cout << "Enter a string: ";
while (getline(cin, s)){
for (int i = 0; i<s.length(); i++){
if ((isspace(s[i]) || isalpha(s[i]))){
for (int i = 0; i < s.length(); i++){
s[i] = toupper(s[i]);
}
cout << s << endl;
return 1;
}
cout << "Invalid string. Please input only alphabets or space character. " << endl << "Enter a string: ";
}
}
//if the input value is valid convert and print
return 0;}
This program successfully make error messages to pure numbers and pure question marks. But the problem is if there are invalid characters and valid characters mixed in the input, it cannot distinguish it.
For example, if input is "Hi?", the program thinks its a valid input. But with questions marks, the string should be invalid.
I think the for statement is the problem. How can I solve this?
I've made a few changes to deal with the break out conditions in your loops without changing the structure of your program too much.
Here's one example how you could get it to work. Comments in the code.
#include <cctype>
#include <iostream>
#include <string>
int main() {
std::string s;
while(std::cout << "Enter a string: " && std::getline(std::cin, s)) {
bool valid = true; // will stay true unless at least one char is invalid
for(char& ch : s) { // use a range-based for loop
// ch is now a reference to the char in the string
// convert to unsigned char - these functions are not safe
// otherwise:
if(std::isspace(static_cast<unsigned char>(ch)) ||
std::isalpha(static_cast<unsigned char>(ch)))
{
ch = std::toupper(static_cast<unsigned char>(ch));
continue; // continue to check the next character
}
std::cout << "Invalid character ('" << ch << "') in string.\n"
"Please input only alphabets or space character.\n";
valid = false; // to let the user enter a new string
break; // no need to check more characters, the string is invalid
}
if(valid) break; // break out only if all characters are valid
}
if(std::cin)
std::cout << "The valid string is now " << s << '\n';
}
A similar program could use algorithms from <algorithm> to do the check and the transformation of the string to uppercase.
Example:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
int main() {
std::string s;
// the manual loop replaced by a simple algorithm that checks if any
// character in the string is invalid by using a lambda, here called
// "is_invalid":
auto is_invalid = [](unsigned char ch) {
return !(std::isspace(ch) || std::isalpha(ch));
};
while(std::cout << "Enter a string: " &&
std::getline(std::cin, s) &&
std::any_of(s.begin(), s.end(), is_invalid))
{
std::cout << "Invalid character in string.\n"
"Please input only alphabets or space character.\n";
}
if(std::cin) {
// transform the valid string to uppercase using another lambda.
// the lambda is here only to make the chars into unsigned chars
// to make the use of std::toupper safe
auto to_upper = [](unsigned char ch) { return std::toupper(ch); };
std::transform(s.begin(), s.end(), s.begin(), to_upper);
std::cout << "The valid string is now " << s << '\n';
}
}
I've tried this but I'm stuck honestly.
I'm trying to find the first character, and then search for the ending of that substring (for eg. if the word is "sandwich" and it finds 's' that it figures out that its "sandwich") and then write out the word sandwich. And also I'm new to C++.
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s, word;
char a;
cout << "Enter the sentence that you desire: ";
getline(cin, s);
cout << "Enter the letter that you want: ";
cin >> a;
for (int i = 0; i < s.length; i++)
{
if (s[i] == a)
{
if (s[i] == '\0')
{
word = s;
cout << word;
}
}
}
return 0;
}
The request is a bit foggy but given also the code you posted, i think i got a heck of what you intend to do.
The easiest (yet not necessarily the most performing one) is to use a stringstream, more precisely an istringstream.
You basically build it with a string (the one you passed from keyboard) and then you use it as if it was your cin (it acts as a normalized istream).
At that point you can iterate each word of the sentence and check the first letter.
The first character of a string is either myString[0] or myString.front(). That is up to you.
the code should look like this :
#include <iostream> //cin/cout
#include <sstream> //istringstream
using namespace std ;
int main()
{
//first of all let's get our sentence AND the character you want
cout << "insert sentence here: " ;
string sentence ;
getline(cin, sentence) ;
cout << "insert the character here: " ;
char letter ;
cin >> letter ;
//then let's create an istringstream with said sentence
istringstream sentenceStream(sentence) ;
//let's then iterate over each word
string word ;
while(sentenceStream >> word)
{
//and see if the word starts with the letter we passed by keyboard
if(word.front() == letter)
{
cout << "the word \"" << word << "\" starts with '" << letter << "'\n" ;
}
}
return 0 ;
}
Just a couple of hints:
iostream includes string already, there is no need to re-include it.
[Edit] (as pointed out by whozcraig, this does not follow the standard. guards will "negate" the double inclusion anyway, so yes, including string is not a mistake. as specified in the comment, i'm yet to find an implementation of iostream that does not include string)[/Edit]
It is good practice not to call a variable 's', or 'a': use a name
that makes it recognizable.
You can find the end of a word with std::find_if:
#include <algorithm>
#include <string>
template <typename Is>
std::string find_word(Is& stream, char needle) {
auto const nonword = [](char c) {
if ('a' <= c && c <= 'z') return false;
if ('A' <= c && c <= 'Z') return false;
if (c == '-') return false;
return true;
};
for (std::string w; stream >> w;) {
if (w.size() && w[0] == needle) {
auto const last = std::find_if(std::begin(w),std::end(w),nonword);
return std::string(std::begin(w),last);
}
}
return "";
}
This takes any stream as argument, including std::cin, and can be invoked like this:
std::cout << find_word(std::cin,'w') << "\n";
It is important to specifically find the last character in each chunk handed you by the stream because the streams will only cut along whitespace by default. So if you enter a sentence:
Hello world!
You want the end of the word to be 'd', not '!'.
I've been stuck on this homework assignment all week. Just when I get the program to finally run, I realize that by using just cin >> breed, if my input has a space it ruins the code (as my program requires gathering 3 separate variables, first an int, then a string, and last a bool). Because this is the second variable, it messes up my code using phrases that have a white character. When I try changing it to cin.get or cin.getline, this is the error message I get:
c2664 error "cannot convert argument 1 from std::string to _Elem *"
Below is the code in question (the middle line is giving the error). Any help would be greatly appreciated!
#include <iostream>
#include <string>
using namespace std;
int main()
{
int birthyear;
string breed;
bool vaccines;
cout << "Please enter value for dog's birth year: ";
cin >> birthyear;
cout << "What is the breed of the dog: ";
cin.getline(breed, 100);
cin.ignore();
cout << "Has the dog been vaccinated (1 = Yes/ 0 = No): ";
cin >> vaccines;
}
First up, you need to be aware that there are two getline things in C++, one in the I/O area and one in the top-level standard namespace.
cin.getline(breed, 100) is the one in the I/O area (specifically istream::getline() and it knows nothing about strings, preferring to work on character arrays. You should probably avoid that one.
The one that does know about strings is std::getline() and that's generally the preferred one if you don't want to go back to the bad old days of C-legacy "strings".
In addition, you need to be careful in C++ when you mix the type-specific input (like <<) and line-specific input (like getline) operations. It's important to know where the file pointer is before and after each operation.
For example, cin << someInt will leave the file pointer immediately after the integer it reads in. That means, if your next operation is getline(), it's likely to find everything on the line after that integer (at the bare minimum, this will be the newline character that you entered to get the integer processed), not the next line where you're going to be typing in your string.
A simple fix for your case is to ignore everything up to and including the newline before you attempt to get the next line. That can be done with ignore():
#include <iostream>
#include <string>
#include <limits>
using namespace std;
int main() {
int birthyear; string breed; bool vaccines;
cout << "Please enter value for dog's birth year: ";
cin >> birthyear;
cout << "What is the breed of the dog: ";
cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
getline(cin, breed);
cout << "Has the dog been vaccinated (1 = Yes/ 0 = No): ";
cin >> vaccines;
// Output what you got.
cout << birthyear << " '" << breed << "' " << vaccines << '\n';
}
You could also opt for ensuring all input is line-based (converting those lines to the correct type once they're entered) since that's likely to ease your task of ensuring the pointers are in the right place, and that errors in input (like entering xyzzy for an integer) can be better handled.
Something like this should be a good start:
#include <iostream>
#include <string>
#include <limits>
#include <set>
#include <cstdlib>
using namespace std;
// Get string, always valid. Optionally strip leading and
// trailing white-space.
bool getResp(const string &prompt, string &val, bool strip = false) {
cout << prompt;
getline(cin, val);
if (strip) {
val.erase(0, val.find_first_not_of(" \t"));
val.erase(val.find_last_not_of(" \t") + 1);
}
return true;
}
// Get unsigned, must ONLY have digits (other than
// leading or trailing space).
bool getResp(const string &prompt, unsigned long &val) {
string str;
if (! getResp(prompt, str, true)) return false;
for (const char &ch: str)
if (! isdigit(ch)) return false;
val = strtoul(str.c_str(), nullptr, 10);
return true;
}
// Get truth value (ignoring leading/trailing space),
// and allow multiple languages.
bool getResp(const string &prompt, bool &val) {
string str;
if (! getResp(prompt, str, true)) return false;
const set<string> yes = {"yes", "y", "1", "si"};
const set<string> no = {"no", "n", "0", "nyet"};
if (yes.find(str) != yes.end()) {
val = true;
return true;
}
if (no.find(str) != no.end()) {
val = false;
return true;
}
return false;
}
// Test driver for your situation.
int main() {
unsigned long birthYear;
std::string dogBreed;
bool isVaccinated;
if (! getResp("What year was the dog born? ", birthYear)) {
std::cout << "** ERROR, invalid value\n";
return 1;
}
if (! getResp("What is the breed of the dog? ", dogBreed, true)) {
std::cout << "** ERROR, invalid value\n";
return 1;
}
if (! getResp("Has the dog been vaccinated? ", isVaccinated)) {
std::cout << "** ERROR, invalid value\n";
return 1;
}
std::cout
<< birthYear
<< " '" << dogBreed << "' "
<< (isVaccinated ? "yes" : "no") << '\n';
}
The purpose of the program is to read a phrase from a file into a vector and convert the phrase into Pig Latin. When the translated phrase is outputted in Pig Latin, an additional "ay" is added after the phrase (which is not supposed to happen). Can anyone spot why this is happening? It is important that I fix this because it affects the total letters and total characters of the Pig Latin phrase that I need to output. Also, I'm not asking anyone to write any code for me, but any tips on how to make my code less redundant. A portion of my grade for programs is efficiency, which I usually lose points on.
Here's the code:
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <stdio.h>
#include <ctype.h>
using namespace std;
int main()
{
ifstream in;
string word, fileName;
vector <string> phrase;
int length = 0, index = 0;
int totalWords = -1, totalLetters = -3, totalChars;
cout << "PIG LATIN PROGRAM" << endl;
cout << "Which file are you accessing? : ";
cin >> fileName;
fileName += ".txt";
in.open(fileName);
if (in.fail()) cout << "\nFile not found!" << endl;
while(getline(in, word)) phrase.push_back(word);
cout << "Original Phrase: " << phrase[0] << endl;
istringstream iss(phrase[0]);
cout << "Pig Latin phrase: ";
do {
string OGword;
string PLword;
for (int i=0; i < phrase.size(); i++){
iss >> OGword;
totalWords++;
}
if (OGword[0]=='a' || OGword[0]=='A' || OGword[0]=='e' || OGword[0]=='E' || OGword[0]=='i' || OGword[0]=='I' || OGword[0]=='o' || OGword[0]=='O' || OGword[0]=='u' || OGword[0]=='U'){
cout << OGword << "way" << " ";
totalLetters += (OGword.size() + 3);
}
else {
PLword = OGword.substr(index);
length = PLword.length();
PLword.insert(length, "ay");
PLword.insert(length, 1, OGword[index]);
PLword.erase(0, 1);
if (isupper(OGword[0])){
transform(PLword.begin(), PLword.end(), PLword.begin(), ::tolower);
(toupper(PLword[1]));
char upper;
upper = toupper(PLword[0]);
PLword.erase(0, 1);
cout << upper;
}
cout << PLword << " ";
totalLetters += PLword.size();
}
} while (iss);
totalChars = totalLetters + 1;
cout << "\n\nTotal words: " << totalWords << endl;
cout << "Total Letters: " << totalLetters << endl;
cout << "Total Characters: "<< totalChars << endl;
}
Problem
The core loop of the program looks like this (in pseudocode):
istringstream iss; // Contains line of text.
do {
string OGword;
get_OGword_and_count_totalWords(iss, OGword);
print_pig_latin_of_word(OGword);
} while (iss);
The loop runs as long as iss has not experienced an error. And in particular, iss does not experience an error until an extraction operation fails. So things happen in the loop like this:
OGword contains the last legitimate word on the line.
Print the last word.
The while clause is tested. iss is still good at this point because no error has occurred, even if iss is at the end of string.
Attempt to extract a word into OGword. This fails, and leaves OGword empty ("").
Print the Pig Latin version of "", which is "ay".
The while clause is tested. iss is in an error state, and the loop ends.
Fix
One possible fix out of many is to test iss for an error immediately after extracting a word.
std::istringstream iss; // Contains line of text
std::string OGword;
while (iss >> OGword) {
increment_word_total();
print_pig_latin_of_word(OGword);
}
In this version, the operation iss >> OGword returns iss, which is converted to bool. If there was an error during the immediately preceeding extraction, the loop ends without printing anything.
Other Advice
I think the best way to improve readability is to break the code up into smaller functions. For instance, take the if / else block that formats and prints the Pig Latin, and actually put it in a function:
int print_pig_latin_of_word_and_return_total_letters(string_view word);
Then, the code in that function can be further subdivided:
bool starts_with_vowel(std::string_view word);
int print_vowel_word_and_count_letters(std::string_view word);
int print_consonant_word_and_count_letters(std::string_view word);
int print_pig_latin_of_word_and_count_letters(std::string_view word) {
if (starts_with_vowel(word)) {
return print_vowel_word_and_count_letters(word);
} else {
return print_consonant_word_and_count_letters(word);
}
}
Odds and Ends
I would drop using namespace std and write all of the std library names as std::string, etc. This makes it clear which things are from the standard library.
The program has interesting behavior on input files that contain more than one line. There is a for loop that loops over phrase.size() which is number of input lines. This causes words to be skipped and totalWords to be incorrect.
This statement doesn't do anything, because the result of toupper is ignored:
(toupper(PLword[1]));
So far, this is my code:
while(bet > remaining_money || bet < 100)
{
cout << "You may not bet lower than 100 or more than your current money. Characters are not accepted." << endl;
cout << "Please bet again: ";
cin >> bet;
}
It works fine but I'm trying to figure out how to make it loop if the user inputs anything that isn't a number as well.
When I press a letter or say a symbol/sign, the code just breaks.
Using the function
isdigit()
This function returns true if the argument is a decimal digit (0–9)
Don't forget to
#include <cctype>
I would use std::getline and std::string to read the whole line and then only break out of the loop when you can convert the entire line to a double.
#include <string>
#include <sstream>
int main()
{
std::string line;
double d;
while (std::getline(std::cin, line))
{
std::stringstream ss(line);
if (ss >> d)
{
if (ss.eof())
{ // Success
break;
}
}
std::cout << "Error!" << std::endl;
}
std::cout << "Finally: " << d << std::endl;
}
A good way of doing this is to take the input as a string. Now find the length of the string as:
int length = str.length();
Make sure to include string and cctype. Now, run a loop that checks the whole string and sees if there is a character that is not a digit.
bool isInt = true;
for (int i = 0; i < length; i++) {
if(!isdigit(str[i]))
isInt = false;
}
If any character is not a digit, isInt will be false. Now, if your input(a string) is all digits, convert it back to an integer as:
int integerForm = stoi(str);
Store integerForm in your array.