#include<iostream.h>
#include<conio.h>
void main()
{
char ch;
cout<<"Enter a character:";
cin>>ch;
if(ch==32)
cout<<"space";
else if(ch>=65 && ch<=90)
cout<<"upper case letter";
else if(ch>=97 && ch<=122)
cout<<"lower case letter";
else
cout<<"special character entered";
getch();
}
I need to check whether character entered is lower or upper case letter,special character, digit or space character. 32 is code for space but as I am entering space as ' ' on the console, its not recognizing ' ' as space.
Spaces are ignored by default, use noskipws
#include<iostream>
using namespace std;
int main()
{
char ch;
cout<<"Enter a character:";
cin>>noskipws>>ch;
if(ch==32)
cout<<"space";
else if(ch>=65 && ch<=90)
cout<<"upper case letter";
else if(ch>=97 && ch<=122)
cout<<"lower case letter";
else
cout<<"special character entered";
getchar();
return 0;
}
Also, if you're adding '' to the space then keep in mind that only the first character is being recognized.
The problem
cin >> ch discards whitespaces (including space, \t, \n, etc.) The correct way is to use get(ch):
cin.get(ch);
(noskipws is another option mentioned in #Samuel's answer, but get may be easier here for a single character.)
Other problems
Use <iostream> instead of <iostream.h>. <iostream.h> is not standard C++.
Use <cstdio>* instead of <conio.h>. <conio.h> is not standard C++.
Use int main() instead of void main(). void main() is not standard C++.
Use indentation instead of left-justifying. Left-justifying is less readable.
Use ch == ' ' instead of ch == 32. ch == 32 is not portable.
Use isupper(ch) instead of ch >= 65 && ch <= 90. ch >= 65 && ch <= 90 is not portable.
Use islower(ch) instead of ch >= 97 && ch <= 122. ch >= 97 && ch <= 122 is not portable.
Fixed code:
#include <iostream>
#include <cctype>
int main()
{
char ch;
std::cout << "Enter a character:";
std::cin.get(ch);
if (ch == ' ')
std::cout << "space";
else if (std::isupper(ch))
std::cout << "upper case letter";
else if (std::islower(ch))
std::cout << "lower case letter";
else
std::cout << "special character entered";
// std::cin >> ch; // only if you really demand it
}
* Even <cstdio> shouldn't be used in this case. If you do want to hold the window open, use getchar() or std::cin >> ch instead of getch(). The better way is to invoke it in a console.
Use characters themselves instead of their codes.
#include<iostream.h>
#include<conio.h>
void main()
{
char ch;
cout << "Enter a character:";
cin >> ch;
if (ch == ' ')
cout << "space";
else if (ch >= 'A' && ch <= 'Z')
cout << "upper case letter";
else if(ch >= 'a' && ch <= 'z')
cout << "lower case letter";
else
cout << "special character entered";
getch();
}
Related
Instructions:
using a value returning function
Write a program that prompts the user to input a sequence of characters and outputs the number of vowels.
This is the problem given by the instructor..
#include <iostream>
using namespace std;
bool isVowel(char ch);
int main() {
char ch;
cout << "Enter a character: ";
cin >> ch;
cout << ch << " is a vowel: " << isVowel(ch) << endl;
return 0;
}
bool isVowel(char ch){
if (ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' ||
ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u'){
return true;
} else
return false;
}
char is a single character, not a sentence. For a sentence use a string.
string s;
cout << "Enter a sentence: ";
cin >> s;
Then use a loop to loop through each character of the sentence
for (char ch : s)
{
...
}
Then use isVowel to test a single character, and increment the count if found. The clue is in the name isVowel, not countVowels, so isVowel should test a single vowel and return true or false, not count the number of vowels.
int vowels = 0;
for (char ch : s)
{
if (isVowel(ch))
vowels++;
}
finally write isVowel to test a single character.
bool isVowel(char ch)
{
return ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' ||
ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u';
}
There are several problems here.
Firstly, you don't initialize vowels. You presumably mean int vowels = 0; or int vowels {0};.
Secondly, you are reading a single character with cin >> ch;. I suspect you mean to loop over an input string.
Thirdly, your signature for isVowel is bool isVowel(int vowels, char ch);, which returns a bool. But you have written your function as thought it is manipulating an integer total of vowels. This inconsistency doesn't make sense.
Fourthly, you assign the result of isVowel to a character in ch = isVowel(vowels,ch);. Then you call isVowel again with this updated ch in cout << isVowel(vowels, ch) << .... I'm not sure what you're attempting to do here, but this also doesn't make any sense.
You need to revisit all of this code. You probably want isVowel to actually return a boolean. You probably want to iterate over an entire input string, and adjust the value of vowels appropriately (after initializing it).
Your program is running an undefined behavior; you are using vowels without being initialized.
You can make function that takes the counter of vowels as a reference to an integer for example.
void isVowel(int& counter, char ch) {
std::string vowels{ "AaEeIiOoUu" };
for (auto c : vowels)
if(ch == c)
counter++;
}
int main(){
char ch;
int counter{};
while (std::cin >> ch)
isVowel(counter, ch);
std::cout << counter << endl << " vowels in this sentence." << endl;
}
#include <iostream>
using namespace std;
bool isVowel(int vowels, char ch);
So isVowel returns a bool. That would make sense if its purpose was to tell us whether a single character was a vowel or not. For some reason, we pass an integer called vowels to it. That doesn't seem to make any sense. What would it do with an integer value?
int main() {
char ch;
So ch is a single character. Okay.
int vowels;
And vowels is an integer with no particular value.
cout << "Enter a sentence: ";
cin >> ch;
Uh oh. We ask the user to enter a sentence but then we read in a single character. Remember, ch was a char.
ch = isVowel(vowels,ch);
Uh oh. We didn't assign vowels any particular value, so we've passed no particular value to isVowel. Also, we took the boolean value returned and assigned to a variable of type char. Why would we do that?
cout << isVowel(vowels, ch) << " vowels in this sentence." << endl;
Then for some reason we call isVowel again. That doesn't make much sense. Also, isVowel returned a bool (a yes or no). Why are we outputting that as if it was the number of vowels?
return 0;
}
// build a string counter and make it callable
bool isVowel(int vowels, char ch){
Okay, so isVowel returns a boolean and takes as input an integer and a character.
for (int i = 0; i < ch; i++){
if (ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' ||
ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u'){
vowels++;
}
We are looping from zero to the value of the single character? That doesn't make sense.
}
return vowels;
}
Lots of problems here. Because there are so many fundamental problems with this code, it seems you've attempted a problem that's way beyond your C++ knowledge and you should attempt something much simpler first, such as accepting a sentence as input and repeating it back to the user without using any additional functions.
So I was originally using cin to have the user input a character. Then if this character isn't a, b, or c, it continues to loop and prints an error message. However, if the user enters multiple characters, it prints the error message multiple times. So now I'm using scanf to take in a string and check if the length is 1. This is straight up just not working at all.
string enterLetter() {
string n;
scanf("%s", &n);
return n;
}
void main() {
string ch = "";
cout << "Type a, b, or c: ";
while (ch != "a" && ch != "b" && ch != "c"){
while (ch.length() != 1) {
ch = enterLetter();
cout << ch.length();
}
ch = tolower((char)ch.c_str());
cout << "\n" << ch;
}
You can't use scanf("%s") with std::string like you are attempting. scanf("%s") expects a pre-allocated char[] instead. If you want to read a std::string, use std::cin.operator>>() or std::getline() instead:
char enterLetter() {
string n;
do {
std::getline(std::cin, n);
}
while (n.length() != 1);
return n[0];
}
int main() {
char ch;
do {
std::cout << "Type a, b, or c: ";
ch = enterLetter();
}
while ((ch != 'a') && (ch != 'b') && (ch != 'c'));
std::cout << ch;
return 0;
}
You don't need to, nor should you use a string for this. Using a char with scanf works better.
int main() {
char ch;
cout << "Type a, b, or c: ";
scanf("%c", &ch);
while ((ch > 'C' && ch < 'a') || ch > 'c' || ch < 'A' ) {
if (ch >= 'A' && ch <= 'Z')
ch += ('a' - 'A');
cout << endl << ch;
cout << endl << "Enter a, b, or c: ";
scanf("%c", &ch);
}
}
This uses scanf to get a char ch. It loops while the char is not a, b, c or A, B, C (as you seemed to want an uppercase use case). If the char is uppercase it gets converted to lower case and then outputs the char.
You could use cin.getline() to read a whole line of user input terminated by the Enter key.
char str[64];
cin.getline(str, sizeof(str));
if the strlen(str) is not equal to 1, an error can be thrown. Otherwise, str[0] can be compared with a, b or c.
If you scanfa string in a loop, it will return the first set of characters terminated by a whitespace (space-bar or new-line char). In the next iteration it will read the next string and so. If a user enters something like "abc def\n", scanf will first return abc followed by def. If you use cin.getline(), all the characters entered until the newline, i.e. "abc def" will be returned in the first call to cin.getline().
I have looked over this for hours it seems like. This program will compile, it just can't detect errors correctly. And for some reason it will work when I type in hey [) or hey {], etc. But it won't work for hey[) or hey{]. Obviously in all cases it should detect an error but for some reason the space after 'hey' makes a difference.
#include<iostream>
#include <stack>
using namespace std;
bool delimiterMatching(char *file){
stack<char> x;
int count = 0;
char ch, onTop, check;
while(ch != '\0'){
ch = file[count];
if (ch == '(' || ch == '[' || ch == '{')
x.push(ch);
else if (ch == ')' || ch == ']' || ch == '}') {
onTop == x.top();
x.pop();
if((ch==')' && onTop!='(') || (ch==']' && onTop!='[') || (ch=='}' &&
onTop!= '{'))
return false;
}
count++;
}
if (x.empty())
return true;
else
return false;
}
int main()
{
char *test = new char();
cout << "enter sentence: ";
cin >> test;
if (delimiterMatching(test))
cout << "success" << endl;
else
cout << "error" << endl;
return 1;
}
With cin >> test you don't get a whole sentence, but only a string until cin encounters whitespace. So if you type (hey ), thest would be (hey and the closing brace would only be read by the next >>, whereas (hey) would work as expected.
You have a second issue with your test allocation, which might be too short for reasonable input.
Change main() as follows:
char *test = new char[256]; // enough space. COnsider also string
cout << "enter sentence: ";
cin.getline(test, 256); // full line input.
...
You have also two nasty bugs in delimiterMatching().
First you use an uninitialized ch in your while condition. Either initialise ch to a non nul char, or use while (file[count]).
And did you notice onTop == x.top(); ? Shouldn't it be onTop = x.top();?
I got conflicting advice with respect to how c++ operates with respect to reading past the eof.
The first group of people state that when the marker is reading past the eof area it reaches the eof and stops while the other group of people state it has to be in the exact position for it to be processed as reaching the eof. To make this clearer let me paste 2 blocks of code.
In this block of code, I am reading a number 1 from the file numbers.txt. They're no syntax errors and the only thing which I didn't paste over here is the code that opens the file.
while (!sample.eof())
{
char ch;
sample.get(ch);
sample.seekp(-1L, ios::cur);
sample >> initialnumber;
sample.seekp(2L, ios::cur);
cout << "OK";
}
In this program here I am reading the number 1 moving back one space making it start from the beginning processing it and then moving two spaces forward. The output for this is OK written only once.
#include < iostream>
#include < fstream>
#include< string>
using namespace std;
string conversion(int);
int conversion2(string);
int main()
{
string initialnumber;
fstream SAMPLE("numbers.txt", ios::in | ios::out);
ofstream sample2("numbers2.txt");
if (sample && sample2)
{
int number2;
string roman;
int number;
char ch;
while (!sample.eof()) {
sample.get(ch);
if (ch != '1' && ch != '2' && ch != '3' && ch != '4' && ch != '5' && ch != '6'
&& ch != '7' && ch != '8' && ch != '9') {
SAMPLE.seekg(-1L, ios::cur);
sample >> roman;
sample.seekg(2L, ios::cur);
sample2 << roman << " " << conversion2(roman) << endl;
int L = sample.tellp();
cout << L;
}
else {
sample.seekg(-1L, ios::cur);
sample >> number2;
sample2 << conversion(number2) << " " << number2 << endl;
sample.seekg(2L, ios::cur);
}
}
}
else
{
cout << "fail";
}
sample.close();
sample2.close();
}
Here it is repeating the number infinite number of times when it shouldn't be repeating it meaning it never reached the eof.
Please help me understand the logic of both programs.
Starting from C++11
Before doing anything else, seekg clears eofbit.
http://en.cppreference.com/w/cpp/io/basic_istream/seekg
Since seekg is always the last thing you call before checking .eof(), it will never be detected. The eofbit is set when a read operation hits the end of file. So, a read must be the last thing you do for it to work.
I must have missed something. I'm doing an exercise to learn c++ and it asks that if a user inputs either c,p,t or g character then carry on, otherwise re-request prompt, so I wrote this:
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main(void){
cout << "Please enter one of the following choices:" << endl;
cout << "c) carnivore\t\t\tp) pianist\n";
cout << "t) tree\t\t\t\tg) game\n";
char ch;
do{
cout << "Please enter a c, p, t, or g: ";
cin >> ch;
cout << "\"" << ch << "\"" << endl;
}while(ch != 'c' || ch != 'p' || ch != 't' || ch != 'g');
cout << "End" << endl;
cin.clear();
cin.ignore();
cin.get();
return 0;
}
This does not work and all I get is the prompt re-requesting it even when pressing either of the correct characters.
However if I change this line:
while(ch != 'c' || ch != 'p' || ch != 't' || ch != 'g');
to
while(ch != 'c' && ch != 'p' && ch != 't' && ch != 'g');
why is that? My understanding is that the "OR" statement should work as one of the tests is correct.
why is that? My understanding is that the "OR" statement should work as one of the tests is correct.
Exactly. There is always one of the tests that passes. A character will either be not 'c', or not 'p'. It can't be both 'c' and 'p'. So the condition is always true, leading to an infinite loop.
The alternative condition with the conjunctions works because it is false as soon as ch is equal to one of the alternatives: one of the inequalities is false, and thus the whole condition is false.
My understanding is that the "OR" statement should work as one of the tests is correct.
Well, you could use ||, but the expression would have to be:
while(!(ch == 'c' || ch == 'p' || ch == 't' || ch == 'g'));
By applying the De Morgan's law, the above simplifies to:
while(ch != 'c' && ch != 'p' && ch != 't' && ch != 'g');