C++ Output giving incorrect amount [duplicate] - c++

This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 4 days ago.
I am trying to write a program that will count the number of words, and number of sentences, and then take the average of those sentences. It takes the input from a user and will stop taking the input upon seeing "###". My code is as follows:
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <string>
using namespace std;
int main() ///Main
{
//1. Declaration of variables
string text;
double word_count = 0.0;
double sentence_count = 0.0;
double avg_words_per_sentence;
//2. Prompt user input
cout << "Enter a paragraph..." << endl;
getline(cin, text, '#'); //3. Use getline to read whole paragraph and not first word entered
//4. Loop to read through text inputted and determine number of words and sentences
for (int i = 0; i < text.length(); i++)
{
if (text[i] == ' ')
{
word_count++;
}
else if (text[i] == '.' || text[i] == '!' || text[i] == '?')
{
sentence_count++;
}
}
//5. Provides error if there is no text
if (word_count == 0 && sentence_count == 0)
{
cout << "Word count: " << word_count << endl;
cout << "Sentence count: " << sentence_count << endl;
cout << "You did not enter any text!" << endl;
}
//6. Provides an error if there are no sentences
else if (sentence_count == 0)
{
cout << "Word count: " << word_count + 1 << endl;
cout << "Sentence count: " << sentence_count << endl;
cout << "You did not enter any sentences!" << endl;
}
//7. Calculates and outputs word/sentence count and average # of words
else
{
word_count++;
avg_words_per_sentence = word_count / sentence_count;
cout << "Word count: " << word_count << endl;
cout << "Sentence count: " << sentence_count << endl;
cout << "Average words per sentence: " << fixed << setprecision(1) << avg_words_per_sentence << endl;
}
return 0;
}
For example: If I were to use the input:
ttt
###
I would expect my word count to be 1, but I am instead told that it is 2. I am unsure as to why it is counting 2.
I tried tweaking certain if/then statements such as if the string contain "#" to not count the word or only count words if there is a space after a proper character but I am still met with the same incorrect number of words

For starters, you have no need to store word and sentence counts as doubles, and this will cause you problems later in your comparisons for conditions:
if (word_count == 0 && sentence_count == 0) should never be done for non integer types.
Your other 'issue' is your own doing, you have 3 cases at the end:
if (word_count == 0 && sentence_count == 0)
{
cout << "Word count: " << word_count << endl;
cout << "Sentence count: " << sentence_count << endl;
cout << "You did not enter any text!" << endl;
}
All is as expected (assuming word_count and sentence_count are not floating point)
else if (sentence_count == 0)
{
cout << "Word count: " << word_count + 1 << endl;
cout << "Sentence count: " << sentence_count << endl;
cout << "You did not enter any sentences!" << endl;
}
When sentence count is 0 but word count is not, you add 1 to the number of words counted. This is what is causing the 'issue' you have described. You do something similar with:
else
{
word_count++;
avg_words_per_sentence = word_count / sentence_count;
cout << "Word count: " << word_count << endl;
cout << "Sentence count: " << sentence_count << endl;
cout << "Average words per sentence: " << fixed << setprecision(1) << avg_words_per_sentence << endl;
}
By adding 1 to word count when you get a nonzero word/sentence count.
I see your intention there, but I think to get your desired behavior, you would just want to account for a word without punctuation as I have added, get rid of the random +1 to word counts, and use integers for comparison as such:
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <string>
using namespace std;
int main() ///Main
{
//1. Declaration of variables
string text;
int word_count = 0;
int sentence_count = 0;
double avg_words_per_sentence;
//2. Prompt user input
cout << "Enter a paragraph..." << endl;
getline(cin, text, '#'); //3. Use getline to read whole paragraph and not first word entered
//4. Loop to read through text inputted and determine number of words and sentences
for (int i = 0; i < text.length(); i++)
{
if (text[i] == ' '|| text[i] == '\n')
{
word_count++;
}
else if (text[i] == '.' || text[i] == '!' || text[i] == '?')
{
sentence_count++;
}
}
//5. Provides error if there is no text
if (word_count == 0 && sentence_count == 0)
{
cout << "Word count: " << word_count << endl;
cout << "Sentence count: " << sentence_count << endl;
cout << "You did not enter any text!" << endl;
}
//6. Provides an error if there are no sentences
else if (sentence_count == 0)
{
cout << "Word count: " << word_count << endl;
cout << "Sentence count: " << sentence_count << endl;
cout << "You did not enter any sentences!" << endl;
}
//7. Calculates and outputs word/sentence count and average # of words
else
{
avg_words_per_sentence = word_count / sentence_count;
cout << "Word count: " << word_count << endl;
cout << "Sentence count: " << sentence_count << endl;
cout << "Average words per sentence: " << fixed << setprecision(1) << avg_words_per_sentence << endl;
}
return 0;
}
Note that this is still not a perfect approach, as multiple newlines will be counted as words. For anything more advanced, you may want to look into a state machine type approach (keep track of if you have encountered a character before newlines and only count words then, for example). Some sample output from this version is below:
Enter a paragraph...
ttt
###
Word count: 1
Sentence count: 0
You did not enter any sentences!
Enter a paragraph...
ttt hehehe.
###
Word count: 2
Sentence count: 1
Average words per sentence: 2.0
Enter a paragraph...
ttt heheh
###
Word count: 2
Sentence count: 0
You did not enter any sentences!
Enter a paragraph...
###
Word count: 2
Sentence count: 0
You did not enter any sentences!

Related

How to shift characters to ASCII values in a file based on user input c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have an assignment using a version of Ceasar cipher but it shifts characters in a file based on user input. For instance, if the user enters the shift value as 1, it would change 'a' to 'b'. I've tried typing to the out file and adding the shift value to the characters but it doesnt output anything to the out1 file and I can't figure out the right way to type this so the code does what I want it to do. Any info would help, here's my code:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cctype>
using namespace std;
double Percent(double&, double&);
int main()
{
//Declare user variables
int shift;
char ifilename[25], ofilename[25], ch;
ifstream in1;
ofstream out1;
double other = 0, letter, nums = 0;
//Attach files
do {
in1.clear(); //clear status flags
//Prompt user to enter name of input file and amount of shift
cout << "Please enter the name of the input file." << endl;
cout << "Filename: ";
cin >> ifilename;
//Open file name
in1.open(ifilename);
//Error message if no file
if (!in1)
cout << "That is not a valid file. Try again\n";
}
while (!in1);
do {
out1.clear(); //clear status flags
cout << "Please enter the name of the output file." << endl;
cout << "Filename: ";
cin >> ofilename;
out1.open(ofilename);
//Error message if no file
if (!out1)
cout << "That is not a valid file. Try again\n";
}
while (!out1);
//prompt user to enter shift
cout << "Please intput the shift amount: ";
cin >> shift;
cout << "Processing complete" << endl;
double count = 0;
int sum = 0, i = 0;
while (!in1.eof()) // while not end of input file
{
in1.get(ch); // read a character from input file using get()
out1 << ch; //print to output
count++; //count how many characters
i = ch;
if (i > 47 && i < 58) //count number of numbers
nums++;
else if ((i > 31 && i < 48) || (i > 57 && i < 65) || (i > 90 && i < 97) || (i > 122 && i < 127))
other++; // count number of other characters
else if ((i > 64 && i < 91) || (i > 96 && i < 123))
letter++; // count number of letters
// type to output file and shift characters
out1 << ch + shift;
}
//Tell user file input is complete and is now printing statistics
cout << "\nShifted input file Complete. Now printing statistics " << endl;
//Show statistics for file
cout << "\nStatistics for file: " << ifilename << endl;
cout << "------------------------------------------------";
//Show characters in file and stats before shift
cout << "\n\nTotal # of characters in file: " << count << endl;
cout << "Statistics before shift: " << endl;
cout << "\n\nCategory" << setw(30) << "How many in file" << setw(20) << "% of file" << endl;
cout << "----------------------------------------------------------------" << endl;
cout << "Letters" << setw(25) << letter << setw(20) << setprecision(4) << letter / count * 100 << " %" << endl;
cout << "Digits" << setw(26) << nums << setw(20) << setprecision(4) << nums / count * 100 << " %" << endl;
cout << "Other" << setw(27) << other << setw(20) << setprecision(4) << other / count * 100 << " %" << endl;
//Show user stats after shift
cout << "\nStatistics after shift: " << endl;
cout << "\n\nCategory" << setw(30) << "How many in file" << setw(20) << "% of file" << endl;
cout << "----------------------------------------------------------------" << endl;
cout << "Letters" << setw(25) << letter << setw(20) << setprecision(4) << Percent(letter, count) << " %" << endl;
cout << "Digits" << setw(26) << sum << setw(20) << setprecision(4) << nums / count * 100 << " %" << endl;
cout << "Other" << setw(27) << nums << setw(20) << setprecision(4) << other / count * 100 << " %" << endl;
//Close files
out1.close();
in1.close();
return 0;
}
double Percent(double&, double&)
{
double sum, letter, count;
sum = letter / count * 100;
return sum;
}
A simple implementation of the Caesar Cipher is to use a string of valid characters and the remainder operator, %.
char Encrypt_Via_Caesar_Cipher(char letter, unsigned int shift)
{
static const std::string vocabulary = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const std::string::size_type position = vocabulary.find(letter);
char c = letter;
if (position != std::string::npos)
{
const std::string::size_type length = vocabulary.length();
c = vocabulary[(position + shift) % length];
}
return c;
}

C++ How would I display characters in a string as a number

I am working on a palindrome program for class. I've written the program and it works. The issue I'm having is the output. I can't figure out how to change the characters into the number they are associated with. Here is my code:
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main ()
{
string word;
int i;
int length;
int counter = 0;
cout << "Please enter a word." << endl;
getline (cin,word);
cout << "The length of the word is " << word.length() << "." << endl;
length = word.length();
for (i=0;i < length ; i++)
{
cout << "Checking element " << word[i] << " with element " word[length-i-1] << "." << endl;
if (word[i] != word[length-i-1])
{
counter = 1;
break;
}
}
if (counter)
{
cout << "NO: it is not a palindrome." << endl;
}
else
{
cout << "YES: it is a palindrome." << endl;
}
return 0;
}
The output I'm getting displays all the characters of the string and looks like this:
my output
Please enter a word
hannah
Checking element h with element h
Checking element a with element a
Checking element n with element n
(etc)
Yes: it is a palindrome.
But, I need the output to display the characters as their placement number in the string, which looks like this:
what output should be
Please enter a word
hannah
Checking element 0 with element 5
Checking element 1 with element 4
Checking element 2 with element 3
Yes: it is a palindrome.
Any hints or tips would be great. I just feel like I've tried everything I know, and it still won't look right. Thank you!
Instead of using :
cout << "Checking element " << word[i] << " with element " word[length-i-1] << "." << endl;
why not use:
cout << "Checking element " << i << " with element " << (length-i-1) << "." << endl;
This line:
cout << "Checking element " << word[i] << " with element " word[length-i-1] << "." << endl;
should be written as
cout << "Checking element " << i << " with element " << length-i-1 << "." << endl;
will give you what you want.

Why does program complain of too many commas?

Here is my code, I have attached the screenshot of what output Zybooks expects, and what my output is. I am trying to get it to output exactly what Zybooks is asking, however something seams to be wrong. It is compiling though. Or maybe Zybooks is just being stupid?
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
#include <cstring>
using namespace std;
int main() {
string title;
string col1;
string col2;
string val;
int numCommas = 0;
vector<string> stringData;
vector<int> intData;
cout << "Enter a title for the data:" << endl;
getline(cin, title);
cout << "You entered: " << title << endl << endl;
cout << "Enter the column 1 header:" << endl;
getline(cin, col1);
cout << "You entered: " << col1 << endl << endl;
cout << "Enter the column 2 header:" << endl;
getline(cin, col2);
cout << "You entered: " << col2 << endl << endl;
while (1) {
cout << "Enter a data point (-1 to stop input):" << endl;
getline(cin, val);
if (val == "-1") {
break;
}
if (val.find(',') == -1) {
cout << "Error: No comma in string." << endl << endl;
}
else {
for (int i = 0; i < val.length(); i++) {
if (val.at(i) == ',') {
numCommas++;
if (numCommas > 1){
break;
}
}
}
if (numCommas == 1) {
stringData.push_back(val.substr(0, val.find(',')));
intData.push_back(stoi(val.substr(val.find(',') + 1, val.length() - 1)));
cout << "Data string: " << val.substr(0, val.find(',')) << endl;
cout << "Data integer: " << stoi(val.substr(val.find(',') + 1, val.length() - 1)) << endl;
}
else {
cout << "Error: Too many commas in input." << endl << endl;
}
}
}
return 0;
}
Thanks.
Thanks.
Your problem is that you initialise numCommas to zero at the start of the program rather than at the start of each author input. That means, once it exceeds one, it will stay that high at least(a), meaning future inputs will always be seen as having too many commas.
You just need to set it to zero immediately before checking each input.
(a) Well, until it wraps around (if it wraps around). But that will be an awful lot of commas you need to input :-)

If and else Statements in While loop" for C++

I have a question regarding if & else statements in a while loop.
I wanted to establish a few things in my program:
wanted user to only input 4 letter characters without the use of numbers and symbols.
converting each those letters into ints(Ascii val.)
To make it easier to understand if confused,
Program 1st asks for 4 letter word.
User places input. If input contains at least:
a non-letter character, then Program asks User for new Input.
If input only contain letters Program checks input for # of letters.
If input doesn't have ___ :
4 letters, Program asks User for new Input.
Otherwise Program proceeds with determining Int value of each letter
Okay so heres my Program so far: ** not sure if this correct for
#include <iostream>
using namespace std;
int main() {
string input;
int input0 = input[0];
int input1 = input[1];
int input2 = input[2];
int input3 = input[3];
cout << "\nEnter a 4-letter word (Keep it clean!).\n";
while(cin>>input){
cout << endl << input << " has " << input.length() << " letters." << endl;
if (int(input[0]) > 64 || int(input[0]) < 91 || int(input[0]) > 96 || int(input[0]) < 123 ||
int(input[1]) > 64 || int(input[1]) < 91 || int(input[1]) > 96 || int(input[1]) < 123 ||
int(input[2]) > 64 || int(input[2]) < 91 || int(input[2]) > 96 || int(input[2]) < 123 ||
int(input[3]) > 64 || int(input[3]) < 91 || int(input[3]) > 96 || int(input[3]) < 123) {
if (input.length()!=5 && input.length()>3)
cout << "\n the int value of the " << input[0] << " is " << int(input[0]) << endl;
cout << "\n the int value of the " << input[1] << " is " << int(input[1]) << endl;
cout << "\n the int value of the " << input[2] << " is " << int(input[2]) << endl;
cout << "\n the int value of the " << input[3] << " is " << int(input[3]) << endl;
else cout << input << "is not a 4-letter word.\nPlease try again." << endl;
}
else cout << input << " contains number(s) and or symbol(s).\nPlease try again." << endl;
}
}
I got 2 errors:
error: expected '}' before 'else'
error: 'else' without a previous 'if'
This fairly gnarly bunch of statements is to blame:
if (input.length()!=5 && input.length()>3)
cout << "\n the int value of the " << input[0] << " is " << int(input[0]) << endl;
// Not part of if-statement:
cout << "\n the int value of the " << input[1] << " is " << int(input[1]) << endl;
cout << "\n the int value of the " << input[2] << " is " << int(input[2]) << endl;
cout << "\n the int value of the " << input[3] << " is " << int(input[3]) << endl;
else cout << input << "is not a 4-letter word.\nPlease try again." << endl;
You need to enclose all those cout statements (up until the else) in braces {, }.
I'd just like to make a point about the character tests you're doing. It looks like you're checking whether the characters are letters, but are using the least-readable, least-portable approach. Use std::isalpha instead. In fact, you can accomplish the whole thing with this:
if( std::all_of( input.begin(), input.begin() + 4, [](char c){ return (bool)isalpha(c); } ) )
{
//...
}
You should do the tests after ensuring the input is the correct length, or you will have undefined behaviour. So let's do that:
while( cin>>input )
{
cout << endl << input << " has " << input.length() << " letters." << endl;
if( input.length() != 4 )
{
cout << input << "is not a 4-letter word.\nPlease try again." << endl;
}
else if( any_of( input.begin(), input.end(), [](char c){ return !isalpha(c); } ) )
{
cout << input << " contains number(s) and or symbol(s).\nPlease try again." << endl;
}
else
{
// I assume you want to exit the loop here.
break;
}
}
Notice I flipped the all_of statement around to the inverse ("any character is not a letter"), for better readability because the lambda no longer needs a cast for automatic type-deduction:
if( any_of( input.begin(), input.end(), [](char c){ return !isalpha(c); } ) ) ...

C++ If Else statement Problems

My code contains an If Else statement. I want it to validate a string that a user inputs puts into the script on two things:
The length of the string has to be more than 0
The string has to consist of alphabet characters
Below is my code, I think the error is to do with the length of the string piece of code.
Before Edit:
cout << "Your word: " << szOriginal << "\n";
if szOriginal.length() > 0 and (isalpha(szOriginal))
{
szWord = szOriginal.tolower();
cout << szWord << "\n";
}
else
{
cout << "Please enter a valid word." << endl;
}
Sorry guys, the error produced by Dev-C++ is
expected '(' before "szOriginal"
Link to printscreen: http://gyazo.com/b3f43928072e9c2a5a8a712a9030364d
After Edit with variable declaration and such:
#include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
using namespace std;
int main(int nNumberofArgs, char* pszArgs[])
{
string original;
cout << "Welcome to the English to Pig Latin translator!\n";
cout << "Type a word you wish to translate:\n";
cin >> original;
cout << "Your word: " << original << "\n";
if (original.length() > 0 && (isalpha(original)) )
{
word = original.tolower();
cout << Word << "\n";
}
else
{
cout << "Please enter a valid word." << endl;
}
system("PAUSE");
return 0;
}
So sorry for this bad post!
if ( [...] ) - you're missing the brackets.
Also, it's && instead of and.
I think you are coming from a python background
cout << "Your word: " << szOriginal << "\n";
if (szOriginal.length() > 0 && (isalpha(szOriginal)) )
{
szWord = szOriginal.tolower();
cout << szWord << "\n";
}
else
{
cout << "Please enter a valid word." << endl;
}
you need ( ) around the if condition, and use && for logical and
EDIT
you are using szOriginal as a char when you say isalpha(szOriginal)
and as an object when you say szWord = szOriginal.tolower();
so you need to look into that also