When I run my program, I have to type how many rows do I want in my output. I have a limit from 1 to 100 rows. Each row is a task with a name of the task followed by increasing number, example: Task1:, Task2, .... When I type something into input, it must convert input string /see the code below - except the code in main();/.
My problem is that when I type first input, it should go to next task/next row/ but it doesnt. I type for example 10 strings but they dont go each to next task but they stay in one task..hope you understand now.
#include<iostream>
#include<string>
#include <ctype.h>
using namespace std;
void Convert(string input){
string output = "";
string flag = "";
bool underscore = false;
bool uppercase = false;
if ( islower(input[0]) == false){
cout << "Error!" <<endl;
return;
}
for (int i=0; i < input.size(); i++){
if ( (isalpha( input[i] ) || (input[i]) == '_') == false){
cout << "Error!" <<endl;
return;
}
if (islower(input[i])){
if (underscore){
underscore = false;
output += toupper(input[i]);
}
else
output += input[i];
}
else if (isupper(input[i])){
if (flag == "C" || uppercase){
cout << "Error!"<<endl;
return;
}
flag = "Java";
output += '_';
output += tolower(input[i]);
}
else if (input[i] == '_'){
if (flag == "Java" || underscore){
cout << "Error!" <<endl;
return;
}
flag = "C";
underscore = true;
}
}
cout << output <<endl;
}
int main(){
const int max = 100;
string input;
int pocet_r;
cout << "Zadaj pocet uloh:" << endl;
cin >> pocet_r;
if(pocet_r >= 1 && pocet_r <=100)
{
for (int i = 0; i <pocet_r; i++)
{
cout << "Uloha " << i+1 << ":" << endl;
while (cin >> input)
Convert (input);
while(input.size() > max)
cout << "slovo musi mat minimalne 1 a maximalne 100 znakov" << endl;
while(input.size() > max)
cin >> input;
while (cin >> input)
Convert(input);
}
}else{
cout << "Minimalne 1 a maximalne 100 uloh" << endl;
}
system("pause");
}
Your first if in Convert will always fail on a non-underscore and return. I don't think that's what's intended. Agree with other answer on the while cin loop. The next two whiles should be if's apparently. Step thru this code with a debugger and watch it line by line and see where it fails. You've got multiple issues here, and I'm not entirely sure what the intent is.
Edit - I didn't parse the extra parenthesis correctly. The first if in convert is actually okay.
Related
I'm quite new to C++, so I apologize if I am not sounding technical. I am having a little trouble getting a multiple input and output with my code, I'm thinking I should have a loop to get the data but i'm not sure how i'd go about that in my code, I've thought about using getline() but that doesn't seem to want to work with Char.
I've tried getline but I'm not sure how to implement it with the Char input, I believe I may need a separate loop as well but again not too sure. I'm thinking it could be done to EoF as well.
Here's my code:
int main()
{
char inpval;
int outval = 0;
cout << "Enter a Roman Number to convert: " << endl;
while (cin.get(inpval))
{
inpval = toupper(inpval);
if (inpval == 'M')
outval = outval + 1000;
else if (inpval == 'D') {
inpval = cin.peek();
inpval = toupper(inpval);
if (inpval == 'M') {
outval = outval - 500;
continue;
} else {
outval = outval + 500;
continue;
}
}
//etc
cout << "The Equivalent Arabic value is:" << endl;
cout << outval << "\n";
return 0;
}
My expected output is:
(All on newline)
Input:
I
II
IV
V
VI
Output:
1
2
4
5
6
Actual output is:
Input:
I
Output:
1
P.S: The program converts Roman Numeral chars to their respected number.
Any help is appreciated!
You can take input multiple items from cin, using below syntax.
cin >> a;
cin >> b;
cin >> c;
Another way is also there
cin >> a >> b >> c;
This technique is called "operator chaining" which is similar to the above.
Do you have any problem doing it like this?
cout << "Enter a Roman Numeral" << endl;
string inpval;
cin >> inpval;
while (inpval != "exit")
{
int outval = 0;
if (inpval == "I")
outval = 1;
else if (inpval == "II")
outval = 2;
else if (inpval == "III")
outval = 3;
else if (inpval == "IV")
outval = 4;
// ect
cout << "The Equivalent Arabic value is: " << outval << endl << endl;
cout << "Enter next numeral: (type exit to exit) " << endl;
cin >> inpval;
}
Method 1: Use getchar(), Calculate/Convert Roman to integer until you encounter a space ' ',when you get a space ' ' output the integer and do the same next roman number until you get another space ' ' or newline '\n' and stop the program once you encounter newline '\n'.
Method 2:Use type std::string and take input with getline. Then iterate through the string and calculate until you find space ' ' output the number, do the same till you find next space ' ' or end when string ends.
If you know # of Roman numbers you want to convert you can put it in a loop.
Hope this helps.
Example(Method 2)
#include <bits/stdc++.h>
int value(char r)
{
if (r == 'I')
return 1;
if (r == 'V')
return 5;
if (r == 'X')
return 10;
if (r == 'L')
return 50;
if (r == 'C')
return 100;
if (r == 'D')
return 500;
if (r == 'M')
return 1000;
return -1;
}
int main()
{
int out=0;
std::string s;
std::string::iterator i; //string iterator
//for more info go to https://www.geeksforgeeks.org/stdstring-class-in-c/
getline(std::cin,s);
for (i = s.begin(); i!= s.end() ; ++i)
{
if(*i != ' ')//Encounter a space, output result and
{ //go to next roman numeral
int s1 = value(*i);
if (*(i+1) != ' ' || *(i+1) != '\0')
{
// Getting value of i+1 nth Element
int s2 = value(*(i+1));
// Comparing both values
if (s1 >= s2)
{
// Value of current symbol is greater
// or equal to the next symbol
out = out + s1;
}
else
{
out = out + s2 - s1;
i++; // Value of current symbol is
// less than the next symbol
}
}
else
{
out = out + s1;
i++;
}
}
else
{
std::cout<<out<<" ";
out = 0;
}
}
std::cout<<out<<" ";
std::cout<<std::endl;
return 0;
}
Input:
I II MM MCMIV
Output:
1 2 2000 1904
The program takes in a word given by the user and translates that to pig latin. I've gotten everything to work almost perfectly, but have run into two bugs. The first of which is when translating words that begin with consonants say "count", the output is "ounttcay" instead of "ountcay". The second bug is that when for three letter words like "egg" or "not" the output is "egg_\377ay" or "ottn\377ay". Is there a simple way to remove that duplicate character and get rid of those numbers?
Note - Unfortunately it has to be done using a Cstring
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
int convertToPigLatin(char arr[50]);
bool isVowel(char ch);
int main() {
char userInput[50];
char answer = ' ';
do {
cout << "Enter a word to convert it to pig latin" << endl;
cin.getline(userInput, 50); //get user input
cout << "Your entered word is " << userInput << endl;
convertToPigLatin(userInput); //translate user's input into piglatin
cout << "Would you like to convert another word?" << endl;
cin >> answer;
cin.ignore(); //clear past user input
cin.clear();
} while (answer == 'Y' || answer == 'y');
return 0;
}
bool isVowel (char ch) {
switch (tolower(ch)) { //if the first character of the given input is a vowel
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return true;
default:
return false;
}
}
int convertToPigLatin(char arr[50]) {
char newArr[50];
// string conjunctions[6] = {"and","but","for","nor","yet","the"}; //list of conjunctions not to be converted
size_t arrLength = strlen(arr); //holds length of input
for (int i = 0; i < arrLength; i++) { //make sure all characters in input are lower case for easier processing
newArr[i] = tolower(arr[i]);
}
char lastChar = newArr[0]; //save the first character in case it needs to be appended
if (atoi(arr) || arr[0] == '\0') { //if the input contains a number or begins with a null character print an error
cout << "Cannot translate inputs that contain numbers" << endl;
return -1;
} else if (arrLength <= 2) { // if the input is 2 or less characters
cout << newArr << endl; //print the input as is
cout << "Boring! Try somthing more than 2 characters long" << endl;
return 0;
} else if ((strstr(newArr, "and") && arrLength == 3) || (arrLength == 3 && strstr(newArr, "but")) || (arrLength == 3 && strstr(newArr, "for")) || (arrLength == 3 && strstr(newArr, "nor")) || (arrLength == 3 && strstr(newArr, "yet")) || (arrLength == 3 && strstr(newArr, "the"))) { //if the input is more than 2 characters long
cout << newArr << endl; //print the input as is
cout << "No conjucntions try again!" << endl;
return 0;
} else { //if the given input is three characters and is not a conjunction, being translation
if (isVowel(arr[0])) { //check if input's first character is a vowel
cout << "Your word in piglatin is "<< strcat(newArr, "ay") << endl; //print that string with 'ay' at the end (i.e. egg'ay')
return 0;
} else { //else if the given input starts with a consonant
for (int r = 1; r < arrLength; r++) {
newArr[r-1] = newArr[r];
newArr[arrLength] = lastChar;
}
cout << "Your word in piglatin is " << strcat(newArr, "ay") << endl;
return 0;
}
}
return 0;
}
You're not terminating newArr, and the last index of the input string is arrLength - 1.
int convertToPigLatin(char arr[50]) {
// Make sure newArr is properly terminated.
char newArr[50] = {0};
// [...]
} else { //else if the given input starts with a consonant
for (int r = 1; r < arrLength; r++) {
newArr[r-1] = newArr[r];
}
// Do this outside the loop.
newArr[arrLength-1] = lastChar;
// No need for strcat here.
cout << "Your word in piglatin is " << newArr << "ay" << endl;
}
}
return 0;
}
You need to add the '\0' at the end of newArr because strlen does not count it so you are not copying it. strcat replaces '\0' witn 'ay\0' but you have no '\0'.
for (int r = 1; r < arrLength; r++) {
newArr[r-1] = newArr[r];
newArr[arrLength] = lastChar;
}
newArr[arrLength+1] = '\0';
cout << "Your word in piglatin is " << strcat(newArr, "ay") << endl;
Basically, this program allows a user to enter a sentence and depending on the users selection, it will show the middle character of the sentence, display it uppercase or lowercase, or backwards. Simple program, but I am new to programming so that may be the problem. I would like to figure out how to use loops instead of a ton of if statements. When I try to make some loops it breaks certain parts of the code but I am sure that is because I don't properly understand them. If you have any criticism or any advice on the code, I'd be happy to hear it. Thanks in advance!
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
int sel;
string sent;
bool validinput;
int i;
int x;
int j;
int a;
cout << "Welcome to my program. Enter a sentence and select one of the options below.\n";
cout << "Enter -999 to exit the program." << endl;
cout << "============================================================================" << endl;
cout << endl;
cout << "1. Display the middle character if there is one." << endl;
cout << "2. Convert to uppercase." << endl;
cout << "3. Convert to lowercase." << endl;
cout << "4. Display backwards." << endl;
cout << "Enter a sentence: ";
getline (cin, sent);
cout << "Selection: ";
cin >> sel;
if (sel < 1 && sel > 4)
{
cout << "Invalid input. Try again. Selection: ";
cin >> sel;
validinput = false;
}
else (sel >= 1 && sel <= 4);
{
validinput = true;
}
if (validinput == true)
{
if (sel == 1)
{
j = sent.length() / 2;
cout << "The middle character is: " << sent.at(j) << endl;
}
if (sel == 2)
{
for (int i = 0; i < sent.length(); i++)
{
if (sent.at(i) >= 'a' && sent.at(i) <= 'z')
{
sent.at(i) = sent.at(i) - 'a' + 'A';
}
}
cout << "Uppercase: " << sent << endl;
}
if (sel == 3)
{
for (int x = 0; x < sent.length(); x++)
{
if (sent.at(x) >= 'A' && sent.at(x) <= 'Z')
{
sent.at(x) = sent.at(x) - 'A' + 'a';
}
}
cout << "Lowercase: " << sent << endl;
}
if (sel == 4)
{
for (a = sent.length() - 1; a >= 0; a--)
{
cout << sent.at(a);
}
}
}
system("pause");
return 0;
}
Personally I would use the switch selection statement. I roughly did this just to explain a bit on how it can make your code more friendly and understandable.
int sel;
bool validInput = false;
switch(sel)
{
case 1:
//display middle char if there's one
case 2:
//convert to uppercase
case 3:
//convert to lowercase
case 4:
//display backwards
validInput = true;
break;
default: //if number does not meat 1, 2, 3 or 4
validInput = false;
break;
}
As you may notice, for case 1, case 2, case 3 and case 4, there's a break just to say that if the number is between 1 to 4; validInput is true.
Reference: Switch Selection Statement
i suggest using a switch. It will organize your code better. From looking at your code you seem to have used for and if wisely. But I suggest the if statements checking for the input be replaced with switch.
I'm nearly finished working on a small guessing game, but i have run into a problem I don't know how to work around.
The problem is with the check_guess function that is checking to make sure the guess being input is a number between 1 and 100.
When running the program the first time, everything works fine.
http://i.imgur.com/pprunDT.png (I would post images if my reputation weren't so low)
But every time after, where yes to play again is chosen, the program runs through the check_guess function and displays "Invalid Input" when it shouldn't
http://i.imgur.com/8OSnSJt.png
I'm not sure why the program is behaving this way.
The code for the entire program is here:
#include <iostream>
#include <cstdlib> //for rand
#include <ctime> //for time
#include <string>
#include <sstream> //for conversions from string to int
using namespace std;
int check_guess(int tries) { //function for limiting the input of guess
string guess = "";
int result = 0;
do {
getline (cin, guess);
istringstream convert(guess);
if ( !(convert >> result) || (result < 1 || result > 100) ) {
result = 0;
cout << "Invalid Input.\n" << endl;
cout << "You have " << tries << " tries: ";
}
} while (result == 0);
return result;
}
bool play_again() { //function for limiting the input of mode
bool quit;
string yn;
do {
cin >> yn;
if ( yn == "y" || yn == "yes" ) {
quit = false;
}
else if ( yn == "n" || yn == "no" ) {
quit = true;
}
else {
yn = "invalid";
cout << "Invalid input.\n\nEnter 'y' or 'n': ";
}
} while ( yn == "invalid" );
return quit;
}
int main()
{
srand(time(0)); //sets seed to be random
int mystery = 0; //defines mystery number
int guess = 0; //defines guess
int tries = 5; //defines trys
bool quit = false; //defines replay or quit
cout << "----------------------------------\n";
do { //while mode is not set to quit, keep playing
tries = 5; //resets tries each new game
mystery = rand() % 100 + 1; //sets mystery number to be random
guess = 0;
cout << "Pick a number between 1 and 100.\n\nYou have 5 tries: ";
while (tries != 0) { //loops until you have no tries left
guess = check_guess(tries);
if (guess == mystery) { tries = 0; } //if you guess right it ends the loop
else { tries--; } //guessing wrong lowers tries by 1
if ( tries != 0 && guess > mystery) {
cout << guess << " is too high.\n" << endl;
cout << "You have " << tries << " tries: ";
}
if ( tries != 0 && guess < mystery) {
cout << guess << " is too low.\n" << endl;
cout << "You have " << tries << " tries: ";
}
}
if (guess == mystery) { //if guess == mystery by time loop ends you win
cout << "Got it! You Win!\n" << endl;
}
else { //if not, you lose
cout << "You Lose! The number was: " << mystery << ".\n" <<endl;
}
cout << "-------------------\n";
cout << "Play Again?(y/n): "; //ask user to play again
quit = play_again();
cout << "-------------------\n";
if (quit == false)
cout << endl;
} while (quit == false);
cout << "----------------------------------" << endl;
return 0;
}
I'm not sure how to fix this.
this line:
cin >> yn;
only reads the 'y' but not the end of line. As a result, the next execution of this instruction
getline (cin, guess);
initializes guess to an empty string.
On line 19, import the code "cin.ignore();" without quotations.
So your code reads as
`int check_guess(int tries) { //function for limiting the input of guess
string guess = "";
int result = 0;
do {
getline (cin, guess);
istringstream convert(guess);
if ( !(convert >> result) || (result < 1 || result > 100) ) {
result = 0;
cin.ignore();
cout << "Invalid Input.\n" << endl;
cout << "You have " << tries << " tries: ";
}
} while (result == 0);
return result;
}
`
and so on. This stops input into the console briefly. You're code is reading the 'y' to try again as the input for the number when you restart as well. Putting in the little line cin.ignore(), stops it from inputting y twice.
Change play_again() to:
bool play_again() { //function for limiting the input of mode
bool quit;
string yn;
do {
getline (cin, yn);
if ( yn == "y" || yn == "yes" ) {
quit = false;
}
else if ( yn == "n" || yn == "no" ) {
quit = true;
}
else {
yn = "invalid";
cout << "Invalid input.\n\nEnter 'y' or 'n': ";
}
} while ( yn == "invalid" );
return quit;
}
I understand that declarations are missing, the code compiles fine however, the output does not output correctly... instead of a letter, I am getting ¿ instead. I believe the problem is in the initialize function, I just cannot seem to figure out what it is....
void printResult(ofstream& outFile, letterType letterList[], int listSize)
{
int i;
int sum = 0;
double Percentage = 0;
cout << "PRINT" << endl;
for (i = 0; i < 52; i++)
sum += letterList[i].count;
outFile << fixed << showpoint << setprecision(2) << endl;
outFile << "Letter Count Percentage of Occurrence" << endl;
for (i = 0; i < 52; i++)
{
outFile << " " << letterList[i].letter << " "
<< setw(5) << letterList[i].count;
if (sum > 0)
Percentage = static_cast<double>(letterList[i].count) /
static_cast<double>(sum) * 100;
/*
Calculates the number of Occurrence by dividing by the total number of
Letters in the document.
*/
outFile << setw(15) << Percentage << "%" << endl;
}
outFile << endl;
}
void openFile(ifstream& inFile, ofstream& outFile)
{
string inFileName;
string outFileName;
cout << "Enter the path and name of the input file (with extension): ";
getline(cin, inFileName);
inFile.open(inFileName);
cout << endl;
cout << "Your input file is " << inFileName << endl;
cout << endl;
cout << "Enter the path and name of the output file (with extension): ";
getline(cin, outFileName);
outFile.open(outFileName);
cout << endl;
cout << "The name of your output file is " << outFileName << endl;
cout << endl;
}
void initialize(letterType letterList[])
{
//Loop to initialize the array of structs; set count to zero
for(int i = 0; i < 26; i++)
{
//This segment sets the uppercase letters
letterList[i].letter = static_cast<char>('A' + i);
letterList[i].count = 0;
//This segment sets the lowercase letters
letterList[i + 26].letter = static_cast<char>('a' + i);
letterList[i + 26].count = 0;
}
}
void count(ifstream& inFile, letterType letterList[], int& totalBig, int& totalSmall)
{
cout << "COUNT WORKING" << endl;
char ch;
//read first character
inFile >> ch;
//Keep reading until end of file is reached
while( !inFile.eof() )
{
//If uppercase letter or lowercase letter is found, update data
if('A' <= ch && ch <= 'Z')
{
letterList[static_cast<int>(ch) - 65].count++;
}
else if('a' <= ch && ch <= 'z')
{
letterList[static_cast<int>(ch) - 97].count++;
}
//read the next character
inFile >> ch;
} //end while
} //end function
===============
driver code
int main()
{
struct letterType letterList[52]; //stores the 52 char we are going to track stats on
int totalBig = 0; //variable to store the total number of uppercase
int totalSmall = 0; //variable to store the total number of lowercase
ifstream inFile;
//defines the file pointer for the text document
ofstream outFile;
//the file pointer for the output file
cout << "MAIN WORKING" << endl;
openFile(inFile, outFile);
//allow the user to specify a file for reading and outputting the stats
/*if (!inFile || !outFile)
{
cout << "***ERROR*** /n No such file found" << endl;
return 1;
}
else
return 1;
*///Check if the files are valid
initialize(&letterList[52]);
//initalizes the letter A-Z, and a-z */
count(inFile, &letterList[52], totalBig, totalSmall);
// counts the letters
printResult(outFile, letterList, 52);
//writes out the stats
//Close files
inFile.close();
outFile.close();
return 0;
}
=====================
Entire Count function
void count(ifstream& inFile, letterType letterList[], int& totalBig, int& totalSmall)
{
cout << "COUNT WORKING" << endl;
char ch;
//read first character
inFile >> ch;
//Keep reading until end of file is reached
while( !inFile.eof() )
{
//If uppercase letter or lowercase letter is found, update data
if('A' >= ch && ch <= 'Z')
{
letterList[ch - 'A'].count++;
}
else if('a' >= ch && ch <= 'z')
{
letterList[(ch - 'a') + 26].count++;
}
//read the next character
inFile >> ch;
} //end while
} //end function
The count logic is confusingly written and that is masking one bug (where it folds the case):
if('A' <= ch && ch <= 'Z')
{
letterList[static_cast<int>(ch) - 65].count++;
}
else if('a' <= ch && ch <= 'z')
{
letterList[static_cast<int>(ch) - 97].count++; // <--- a bug here
}
This reacts to 'a' by incrementing the count for the first element, which looks like it is intended to be the count for 'A'. This is easily fixed by offsetting lowercase, also rewriting it so it is clearer what is being done:
if ('A' <= ch && ch <= 'Z')
{
letterList[static_cast<int>(ch - 'A')].count++; // count uppercase
}
else if ('a' <= ch && ch <= 'z')
{
letterList[static_cast<int>(ch - 'a') + 26].count++; // count lowercase
}
As for the main bug, initialize() is not called anywhere.
Initialize is being called incorrectly as initialize(&letterList[52]); This attempts to initialize entries 52, 53, ... 103. I am surprised it doesn't segfault.
It should be called as
initialize(letterList);
Your functions are doing just right.
In your driver code you are calling these functions with wrong argumnets
Check these lines they should be like this
initialize(&letterList[0]);
//initalizes the letter A-Z, and a-z */
count(inFile, &letterList[0], totalBig, totalSmall);
While passing letterList array to the functions you should pass the pointer to first element in the array. you should pass &letterList[0] or simply letterList