I'm new to this and currently studying C++. I'm currently learning about Character Functions in cctype(ctype). I'm having trouble understanding why the isspace(a_character) is not returning my cout message -- the problem is it wont even accept my Char user input. Any help or steering to the right direction would be greatly appreciated. I can achieve the response I want if I assign the Char value of: ' ' , however, it defeats the purpose. I've copied a portion of my code. To my understanding, there's no exact symbol for Whitespace? if so, is it possible to even enter a whitespace as an input? I've tried entering : ' ' however, have not been successful. Again, I'd greatly appreciate it.
#include <iostream>
#include <cctype>
#include <ctype.h>
using namespace std;
int main()
{
char c ;
char ans = 'y' || 'Y';
do {
cout << "Enter a character \n";
cin >> c;
if (isspace (c)) //Having trouble get this to actually produce a value
{
cout << "Your character " << c << "is a whitespace";
}
if (ispunct(c))
{
cout << c << " is a punctuation character\n";
}
cout << "Would you like to enter another value? \n";
cin >> ans;
} while (ans == 'Y' || ans == 'y');
return 0;
}
>> is a formatted extractor. Formatted extractors, by default, extract and discard all whitespace characters before they actually read anything. That's useful behavior, but not when you are trying to read a whitespace character.
Either use unformatted input (get()) or the noskipws manipulator. Note that your later reading of ans in all likelihood depends on skipping whitespace to work correctly, so you'd probably want to restore the whitespace-skipping behavior with skipws after you read c if you choose the second option.
Related
I'm trying to solve the question in programming : principles and practice using c++
Q. make a code that reads two int values and prints them. Make '|' input stop the program.
use while loop
I have no idea to distinguish whether the input is int or '|'
This question:
make a code that reads two int values and prints them. Make '|' input stop the program. use while loop
indicates that author doesn't know c++ well or task was stated for different language. It is also possible you didn't copy paste whole description of task.
When next character to read is | trying reading integer value will fail, so no special check has to be done.
So just read pairs of int values until error occurs. Special check for | is obsolete.
int a, b;
while (std::cin >> a >> b)
std::cout << (a + b) << '\n';
https://godbolt.org/z/P95z4a
Here is a solution.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string value1, value2;
while(1) //infinity loop
{
cout << "Enter value one" << endl;
cin >> value1;
cout << "Enter value two" << endl;
cin >> value2;
if(value1 == "|" || value2 == "|") // the || is a logical OR. If v1 oder v2 is | break the while loop
{
break;
}
cout << value1 << " + " << value2 << " = " << (std::stoi(value1)+std::stoi(value2)) << endl; //std::stoi makes a string a number, so it means string to int
}
return 0;
}
Compile it with the c++11 flag for stdoi:
g++ -std=c++11 example.cpp -o example
PS: don't ask stackoverflow to do your homework for you. Try to learn for yourself. You will need it in the job and your colleagues will depend on you.
You can pour your input into string type variable cin >> tmp_str. Then check if it is euqal to '|', if not you can convert it to integer using stoi or any alternatives.
Try reading the user input as a string and checking whether it's equal to |:
#include <iostream>
#include <string>
int main() {
std::string input;
while (input != "|") {
std::getline(std::cin, input);
// read int values here
}
}
Alright guys so I'm learning C++ using Bjarne Stroustrup's Programming Principles and Practice Using C++ book, and one of the drills asks me to
Step one: Enter a number followed by a unit(allow cm, m, in, and ft)
Step two: Convert that number into meters and output it
Step three: Reject any unit that the program doesn't know how to convert
Step four: Reject any values without units
Here is what I have so far:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
inline void keep_window_open() { char ch; cin>>ch; }
int main()
{
constexpr double cm_to_m = 100;
constexpr double cm_to_in = 2.54;
constexpr double in_to_ft = 12;
double i, in_meters;
string unit;
while (cin >> i)
{
cin >> unit;
if(unit == "cm" || unit == " cm") {in_meters = i / cm_to_m; cout << "That is " << in_meters << "m" << endl;}
else if(unit == "in" || unit == " in") {in_meters = i * cm_to_in / cm_to_m; cout << "That is " << in_meters << "m" << endl;}
else if(unit == "ft" || unit == " ft") {in_meters = (i * in_to_ft) * cm_to_in / cm_to_m; cout << "That is " << in_meters << "m" << endl;}
else if(unit == "m" || unit == " m") {cout << "That is " << i << "m" << endl;}
else if() cout << "You need to enter a unit after the number(cm, m, in, ft)" << endl;
else cout << "I don't know that unit" << endl;
}
}
My problem is at step four. I cannot, for the life of me, figure out how to check if no unit has been entered after the number. I've tried if(unit == " "), and everything similar to that, but when I just type in a number, it continues until I type in a unit.
If you guys can help with just giving hints so I can figure it out myself, that would be helpful :)
TIA
I think you could wait till there is a \n(end of line) and check if there is no unit
First off, you should always check whether input is successful after an attempt to read it. To do so, you'd check the stream state. Typically, that's done in combination with the read, e.g.:
if (std::cin >> unit) {
// ...
}
else {
// deal with no input being received
}
From the looks of it you want to constrain where the unit is located relative to the previous value: it seems you want the unit to be directly adjacent to the value or separated with at most one space. The input operator for std::string, like all well-behaved input operators, starts with skipping leading whitespace by default. If you don't want to allow arbitrary whitespace, you'll need to test for that explicitly.
When you want to allow at most one space character, you would need to deal with that explicitly. To do so you'd peek() at the next character and if it is a space (' ') you'd ignore() it. Next you can either disable skipping of leading whitespace using std::noskipws or peek() at the next character and fail if it is a whitespace character (std::isspace()). The next step would be reading the unit.
That is, reading the unit immediately after the value could look like this:
if (std::cin.peek() == ' ') {
std::cin.ignore();
}
if (std:cin >> std::noskipws >> unit >> std::skipws) {
// see if unit is a valid unit
}
else {
// no unit was entered where expected
}
The unit variable won't include a space character unless you read the string differently, e.g., using std::getline(). Thus, you can simply check the unit against "cm", "in", etc. There is no point to check it against " cm" for example as this test will always fail.
In addition I'd also get rid of the if () in your code: it serves no purpose other than adding confusion. I'm not even sure whether it is legal. gcc and clang both refuse to compile code containing an if-statement with an empty condition.
Finally, instead of keep_window_open() I'd just wait for some input using std::cin.ignore();. If you insist in keeping this function, its implementation could still be simplified to become std::cin.ignore();.
I actually wrote a function to convert string into ascii values.
However I managed to confuse my self and don't understand why my own code works.
here it is:
void convertToString()
{
char redo;
int letter;
int length;
do {
cout<< "How long is your word \n";
cin >> length;
cout << "Type in the letter values \n";
for (int x = 0; x < length; x++) {
cin >> letter;
cout << char (letter);
}
cout << "\n To enter another word hit R" << endl;
cin >> redo;
} while (redo == 'R');
}
In the terminal I can type in all the ASCII values I want with out changing line, however I though this would cause a problem, anyways my question is, is hitting the enter button the same as hitting space? if not i dont understand how my code is able to print out the chars since i write it all in one line...Does it assign the interger "letter" a new value everytime there is a space?
Please help/explain
This is to expand a bit on what Igor said in his comment and to give a little example.
As Igor said, istream::operator>>(&int) will read non-whitespace. This means for each call on the operator, it scans along the input stream (what you typed in) for non-whitespace and reads until the next whitespace again. The next call will pick up where you left off. So, entering a space or a newline is exactly the same for this situation where you're taking in an int.
You can verify this with a simple bit of code that scans until EOF:
#include <iostream>
int main()
{
int number;
while (std::cin >> number)
{
std::cout << number << std::endl;
}
return 0;
}
This will wait for user entry to be complete (pressing enter), but print a new line for each integer in your input as separated by whitespace. So "1 2 3 4" will print each of those numbers on separate lines, regardless of if you separate them with spaces, tabs, or newlines.
So recently, I came across using isdigit as a way to check to see if an entered value for an int is actually an integer, rather than a string or a char.
However, when I wrote a short program to play around with that, the program failed to execute from that point on.
EDIT: I also in the program wanted to take the invalid data and convert it to a different data type.
Here is the code:
#include <iostream>
#include <sstream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
int enterCFN;
char revisit;
int review(0);
cout << "Enter a digit: ";
cin >> enterCFN;
bool y = isdigit(enterCFN);
if (y == false)
{
// This is the data conversion section
revisit = enterCFN;
revisit = review;
cout << review << "\n";
}
else
{
cout << enterCFN << "\n";
}
return 0;
}
Is there anyone who can correct my error and show me what I'm doing wrong?
enterCFN is an int. It stores a number. isdigit() checks if a character represents a number. These are not the same thing: for example 32 is a number but char(32) means ' ' (space).
What you want instead is this:
if (cin >> enterCFN)
That will take the input from the user and check if it is valid all at once. No need for isdigit().
isdigit() checks if a given character is one of 0-9
For validating integer do something like following:
std::cout << "Enter a digit: ";
std::cin >> enterCFN ;
while (1)
{ if ( std::cin >> enterCFN )
{
// good input
break ;
}
else
{
std::cout << "Enter a digit: ";
// clear stream flags set due to bad input
std::cin.clear();
// get rid of the bad input.
// ignore the rest of the line
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
I am making a very simple programs just trying to learn c++ as a beginner. It is designed to simply count the number of vowells and the number of consenants in a short sentence. I have come across an interesting little dilema while doing it.
First of all here is the code:
#include <iostream>
#include <time.h>
#include <string>
using namespace std;
int main()
{ int vowells = 0, consenants = 0;
char sentence[100];
char alphabet[] = {'a','e','i','o','u','b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z'};
cout << "Please type in a sentence (up to 100 characters max, lower case only): ";
cin >> sentence;
cin.ignore();
cout << "Your sentence was: " << sentence;
for (int i=0; i < sizeof(sentence); i++)
{
if (sentence[i] == alphabet[0]||sentence[i] == alphabet[1]||sentence[i] == alphabet[2]||sentence[i] == alphabet[3]||sentence[i] == alphabet[4])
{vowells++;}
else if (sentence[i] == alphabet[5]||sentence[i] == alphabet[6]||sentence[i] == alphabet[7]||sentence[i] == alphabet[8]||sentence[i] == alphabet[9]||sentence[i] == alphabet[10]||sentence[i] == alphabet[11]||
sentence[i] == alphabet[12]||sentence[i] == alphabet[13]||sentence[i] == alphabet[14]||sentence[i] == alphabet[15]||sentence[i] == alphabet[16]||sentence[i] == alphabet[17]||sentence[i] == alphabet[18]||
sentence[19] == alphabet[20]||sentence[i] == alphabet[21]||sentence[i] == alphabet[22]||sentence[23] == alphabet[24]||sentence[i] == alphabet[25])
{consenants++;}
}
cout << "\nThe number of vowells is: " << vowells;
cout << "\nThe number of consenants is: " << consenants;
cin.get();
}
Sorry it looks really messy. Basically after the cin >> sentence; line i put the cin.ignore() function to get rid of the enter key pressed after inputing the sentence. At the end of the function the cin.get() is simply suppose to serve as a breaking point so that the program wants another input before it closes. If i input just 1 word with no spaces, the program runs and pauses at the end as desired. If i put in multiple words with spaces, it just runs and closes immediately without giving me time to even see it. I assume this is because of the spaces for some reason... Though i'm not sure why they would affect it in this way.
So basically, is it the spaces that are giving me my problems? If so how do i go about either getting rid of them or at least having the program ignore them?
Thanks!
EDIT*** So i was told that i could use the windows Sleep() command to get it to pause, and that worked. Now the problem is that as another person commented, the cin function only accepts the first word, and doesn't take into account the rest of the sentence. So i guess i need to get rid of the spaces or somehow use a different input function to get it to work properly. Any suggestions on how to go about doing this?
From what I know, there is no standard, cross-platform way to "Sleep" in C++. If you're running Windows, you can use the following:
#include <windows.h>
int main(){
//do stuff
Sleep(1000); // this will "sleep" for 1s (1000ms)
}
If you aren't using Windows, I'm sure there are Linux/etc alternatives out there as well to do something similar. I've seen your way used before, but if it isn't working, this should be a nice alternative. You could use threads, for example. That could work.
Yes, the spaces are giving you problems. >> stops extracting characters into the buffer when a whitespace character is encountered. So if you have one word followed by a space then another word, only the first word is placed in the buffer with a single call to >>. Your later call to cin.get already has a character to read form the stream since they were not all taken by the >> call.
getline provides a way to extract whitespace as well as other characters.
//cin >> sentence;
//cin.ignore();
cin.getline(sentence, 100)