Console Application Exits Automatically C++ - c++

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)

Related

Unable to detect enter key in C++

Now, before this question gets marked for duplicate. I have already gone through most of the questions and their relative answers of C++. These are the links that I have tried and none of them work for me. It maybe because they are using an older version of C++, and I have the latest version of C++. Here are the links that I have tried:
Detecting ENTER key in C++
https://www.sololearn.com/Discuss/1863352/how-can-i-check-that-user-press-enter-key-in-c
http://www.cplusplus.com/forum/beginner/2624/
https://www.dreamincode.net/forums/topic/398680-detect-enter-key/
Now, with the duplicates out of the way. I am making an expression calculator. So, for example if the user input is: 2+2*6*9/9, then the output should be 14.
The code where I suspect that the problem lies is in:
#include <iostream>
#include <vector>
using std::cout;
using std::cin;
using std::string;
using std::vector;
void clear();
void error(string message);
int main() {
cout << "Enter an expression: ";
double l_Value = 0, r_Value = 0, result = 0, count = 0, previous_number;
char op;
while (cin >> l_Value) { // 1+2*3+6-4/2+3
if (!cin) {
error("Invalid operand entered!");
}
else {
bool is_Error = 0; // false
vector<double> numbers;
numbers.push_back(l_Value);
previous_number = l_Value;
while (cin >> op) {
if (op == '\0') {
break;
}
cin >> r_Value;
switch (op)
{
case '+':
numbers.push_back(r_Value);
previous_number = r_Value;
break;
case '-':
numbers.push_back((-1 * r_Value));
previous_number = (-1 * r_Value);
break;
case '*':
numbers.pop_back(); // take out the number
r_Value *= previous_number;
numbers.push_back(r_Value);
previous_number = r_Value;
break;
case '/':
if (r_Value == 0) {
error("Sorry, division by zero has occured. Please re-evaluate your expression!\n");
is_Error = 1; // true
break;
}
else {
numbers.pop_back(); // take out the number
previous_number /= r_Value;
numbers.push_back(previous_number);
break;
}
}
}
if (!is_Error) {
for (int i = 0; i < numbers.size(); i++) {
result += numbers[i];
}
cout << result << '\n';
}
numbers.clear();
result = 0;
l_Value = 0;
r_Value = 0;
}
cout << "Enter an expression: ";
}
clear();
return 0;
}
None of the links above seemed to work for me.
When I press the Enter key, it expects me to give another input, and that is not supposed to happen. So when I used cin.get() == 'n' or cin.get() == (int)'\n', it expects for another input. But, when I have an 'x' at the end of the expression, it works perfectly fine. So, I need the "cin" operator to help me detect an Enter character at the end of the expression and then terminate the program.
Here, is a sample run of a program with 'x':
[![running as x-terminator][1]][1]
[1]: https://i.stack.imgur.com/ORPQa.png
When I try the above solution such as "cin.get() == '\n':
Then, I thought that maybe it is reading the null character and so, I tried if (op == '\0'):
For the enter key and null character I had to press Ctrl+Z to terminate the program. Please help!
As, mentioned by user #idclev, I already have a string program that works, but I am trying to avoid using string to calculate any expressions! So, if I could detect an enter key pressed using a character datatype that would be great!
I avoided strings to avoid parsing through the text
That argument is moot. What you can read from cin you can also read from a std::string, no difference whatsoever. You just need to add one step:
#include <iostream>
#include <string>
#include <sstream>
int main( ){
std::string x;
std::cin >> x;
if (x == "") {
std::cout << "user pressed enter (and nothing else)";
} else {
double y;
std::stringstream ss{x};
ss >> y;
std::cout << y;
}
}
This will read one std::string. If user only hit enter then the string will be empty. If the user entered something the else branch will be taken and you can extract the number from the string in the same way you did extract the number from cin (via using a std::stringstream).
If you have more than one number in the input you need to use getline to read the string, because cin will (by default) only read till the next whitespace.
Again...
If I used a string, I would have a tough time in extracting single-digit and two-digit or n-number of digits in a string. The double data type does that for me
You can read single-digit or any number of digits from a stringstream in exactly the same way as you read them from cin.
I already made a program with string in it. I was trying to avoid string to see how much faster would it be without string.
It won't be any faster. Constructing the string and the stringstream is maybe in the order of microseconds. A user entering input is in the order of seconds, maybe milliseconds when they are typing very fast.
Your approach cannot work because hitting enter is not considered as a character. Trying to read a character when there is none in the stream will fail. It will not set the character to \n or \r.
On the outer loop, you are trying to read a double, but you keep pressing enter. There is no input to evaluate, so it keeps trying to read a double. You can get out of it by ending the input stream with ^Z, or you can give it any actual content to read, and it will try to make it into a double (which is what your code explicitly told it to wait for).
Basically, when you press enter, it's ignoring it because
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
Extracts as many characters as possible from the stream and inserts them into the output sequence controlled by the stream buffer object pointed by sb (if any), until either the input sequence is exhausted or the function fails to insert into the object pointed by sb.
Try experimenting with this to see what is happening.
#include <iostream>
#include <vector>
#include <string>
int main() {
double x;
std::cin >> x;
std::cout << "read this value: " << x << std::endl;
// this is what while or if will look at
bool success = !std::cin.fail();
if (success)
std::cout << "success" << std::endl;
else
std::cout << "failure, loop will exit" << std::endl;
return 0;
}
What you should want (in my opinion) is a function that takes the expression as a string, and returns the result, so you can write unit tests, and make sure the function works. You can use this function with any expression that you can put in a string. It doesn't HAVE to be typed in by a user.
If you want the user to type in the experession, it's a lot easier to just use getline() then pass the string to your function. The big problem with using cin on each variable and character is that the user has no idea which datetype is expected right then. Granted, it's not hard to guess with an expression, but you wrote it and debugged it and still didn't know which cin you were failing to get the right datatype to. (this is normal, btw -- been there, which is why I getline and parse separately)

Isspace Character Function

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.

C++ if condition not checked after goto

I'm working on a simplish game (this isn't the whole code, just the bit that I'm having issues with) and I've run into this issue; After the condition is furfilled, it goes back to the start and it offers me to reenter the string, however, whatever I enter, I just get 'Not Valid'. Does anyone know why? I'm using the GNU C++ Compiler.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string command;
mainscreen:
cout << "blab";
getlinething:
cin.ignore();
getline(cin, command);
if (command == "task")
{
goto mainscreen;
}
else
{
cout << "Not valid.";
goto getlinething;
}
return 0;
}
When I run your code with a debug print it shows that each time you read a new command you are loosing the first char of the string. In fact, when I remove your cin.ignore() it works fine.
Also, have a look at this while to see if it fits your needs:
cout << "blab";
while(1){
getline(cin, command);
if(command == "task"){
cout << "blab";
getline(cin, command);
}
else{
cout << "Not valid.";
}
}
For debugging purpose at least, why not do
cout << "'" << command << "' Not valid" << endl ;
Alright, I tested it out. Without cin.ignore(), I cannot enter the data into the string at all.
The first time I enter it captures everything. So if I wrote task, the string would say 'task', however the second time I entered it, it would say 'ask'. I don't really know why it's doing that.
The cin.ignore() line will always discard one character by default (unless it encounters EOF, which would be a fairly deliberate act on cin).
So, let's say the user enters task and then hits the enter key. The cin.ignore() will discard the 't', and the command string will contain "ask". If you want to get a match, the first time through, the user will need to enter ttask. The newline will be discarded, in either case. The same will happen until a match is encountered.

Why is this code exiting at this point?

I'm new to C++. I stumbled upon one tutorial problem, and I thought I'd use the few things I have learnt to solve it. I have written the code to an extent but the code exits at a point, and I really can't figure out why. I do not want to go into details about the tutorial question because I actually wish to continue with it based on how I understood it from the start, and I know prospective answerers might want to change that. The code is explanatory, I have just written few lines.
Here comes the code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
double average_each_student() {
cout << "\n>Enter your scores seperated by spaces and terminated with a period\n"
<< ">Note: scores after total number of six will be truncated.\n"
<< endl;
double sum = 0, average = 0;
int user_input, counter = 0;
const double no_of_exams = 6;
while(cin >> user_input) {
++counter;
if(counter < 5) sum += 0.15 * user_input;
else if(counter > 4 && counter < 7) sum += 0.20 * user_input;
}
return sum / no_of_exams;
}
int reg_number() {
cout << "Enter your registration number: " << endl;
int reg_numb;
cin >> reg_numb;
return reg_numb;
}
int main() {
vector<int> reg_num_list;
vector<double> student_average;
reg_num_list.push_back(reg_number());
student_average.push_back(average_each_student());
string answer;
cout << "\n\nIs that all??" << endl;
//everything ends at this point.
//process returns 0
cin >> answer;
cout << answer;
}
The code exits at cout << "\n\nIs that all??" << endl;. The rest part after that is not what I intend doing, but I'm just using that part to understand what's happening around there.
PS: I know there are other ways to improve the whole thing, but I'm writing the code based on my present knowledge and I wish to maintain the idea I'm currently implementing. I would appreciate if that doesn't change for now. I only need to know what I'm not doing right that is making the code end at that point.
The loop inside average_each_student() runs until further input for data fails and std::cin gets into failure state (i.e., it gets std::ios_base::failbit set).
As a result, input in main() immediately fails and the output of what was input just prints the unchanged string. That is, your perception of the program existing prior to the input is actually wrong: it just doesn't wait for input on a stream in fail state. Since your output doesn't add anything recognizable the output appears to do nothing although it actually prints an empty string. You can easily verify this claim by adding something, e.g.
std::cout << "read '" << answer << "'\n";
Whether it is possible to recover from the fail state on the input stream depends on how it failed. If you enter number until you indicate stream termination (using Ctrl-D or Ctrl-Z on the terminal depending on what kind of system you are using), there isn't any way to recover. If you terminate the input entering a non-number, you can use
std::cin.clear();
To clear the stream's failure stated. You might want to ignore entered characters using
std::cin.ignore(); // ignore the next character
or
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// ignore everything up to the end of the line
use cin.clear(); before cin >> answer; That will fix the problem. But you are not controlling the input. it just runs out to cin..

while loop and getchar()

I have the simple program below that I wrote for a college course. I know it doesn't really do anything, but it's just an assignment for a course.
The part that I can't figure out, is why doesn't the outer loop work?
The user needs to press '1' to continue, and any other key the program exits.
However, it still doesn't continue if the user presses '1' and instead exits anyway.
I tried adding a cin.clear() before cin >> repeat, but that doesn't work.
I also tried playing around with cin.ignore(), but that didn't seem to help either.
Any ideas?
Thanks
int main()
{
int repeat = '1';
stack<char> cstr;
char c;
while (repeat == '1')
{
cout << "Enter in a name: ";
while (cin.get(c) && c != '\n')
{
cstr.push(c);
}
cout << "\n Enter another name? 1 = Continue, any other key to exit the program";
cin >> repeat;
repeat = getchar();
}
}
There is nothing at all wrong with your code. It seems to be working fine for me.
EDIT: Sorry it doesn't work until you remove the getchar. Forgot to mention that. Simple way of finding out the error is to just display the value of the variable repeat to see what the value is and where it is going wrong.
Screenshot to show you that your codes work
Everything seems to be working fine. I would like to comment on your program structure though. For small programs like this it's ok but always best to practice the logical way. For questions like this you should implement the do while loop instead of the while loop so that it goes in without checking and then accepts the user input and checks with the post condition. Example below.
char repeat;
do
{
//Your codes in here
}while (repeat == '1');
It is more logical to use this method instead unless your question specifies you to use while loop. Anyhow hope this helps.
Run this . it will solve your problem somehow repeat=getchar was making repeat=10.
int main()
{
char repeat = '1';
stack<char> cstr;
char c;
while (repeat == '1')
{
cout << "Enter in a name: ";
cin.ignore();
while (cin.get(c) && c != '\n')
{
cstr.push(c);
}
cout << "\nEnter another name ? \nPress 1 to Continue : ";
cin >> repeat;
cout << endl;
}
system("pause");
}
The line cin >> repeat is tring to read an integer from the keyboard because repeat is a variable of type int. However, you are verifying if the integer read from the keyboard is equal to 49 (the ASCII code for the character '1'), which is not what you want. A solution would be to replace the line
int repeat = '1';
with
int repeat = 1;
and also replace
while (repeat == '1')
with
while (repeat == 1)
because then you are comparing the integer read from the keyboard with the integer 1 (rather than the character '1'). Also, at the end of the loop you read input from the keyboard and store it in repeat but then you immediately read input again and store that value in repeat, replacing its previous value. To solve this, replace the line
repeat = getchar();
with
getchar();
and that should do it.
cin >> repeat;
it reads repeat as int. (1 is not equal '1')
repeat = getchar();
It reads int code of special char '\n' - symbol end of line.
You must use
char repeat = '1';
Or write
int repeat = 1;
and not use getchar()