I'm currently working on making a little word processor and I've come across an issue. I'm trying to make the program so that when you press enter, the program will put a full stop on your input and then a space (I'll sort out paragraphs later). The issue is that I can't get the program to search the last character for punctuation and then branch on the result. The compiler gives me the following error: ISO C++ forbids comparison between pointer and integer. The code I currently have is:
#include <fstream>
#include <string>
#include <iostream>
#include <cstring>
#include <limits>
using namespace std ;
int main()
{
int i = 0;
string text ;
string text2 ;
string title ;
string usertitle ;
string filelocation = "C:/Users/" ;
string user ;
string punctuation = ". : ! ? "
cout << "Input a title for your file: " ;
getline(cin , title) ;
title.insert(title.length() , ".txt" ) ;
cout << "Your title is: " << title << endl ;
cout << endl << "Input the username associated with your computer: " ;
getline(cin , user) ;
filelocation.append( user ) ;
filelocation.append("/Documents/") ;
filelocation.append(title) ;
cout << "Your chosen file name and location is: " << filelocation << endl ;
for ( i = 1 ; i > 0 ; i++ )
{
if (text == "")
{
cout << "There are a few instructions that you need to follow in order to use this system effectively: " << endl ;
cout << "The first being that if you want to use it, you actually have to use a directory that exists. " << endl ;
cout << "The second being that when you want to exit the program you press enter with nothing typed" << endl ;
cout << "The third being NOT TO USE FULL STOPS, THE PROGRAM WILL PUT THEM IN FOR YOU" << endl ;
cout << "Please begin writing: " << endl ;
getline(cin,text) ;
}
if (text!="")
{
text2.append(text) ; //<===HERE IS WHERE I AM HAVING TROUBLE
if ((text.at(text.size() -1 ) != "!" ) && (text.at(text.size() -1 ) != "?") && (text.at(text.size() -1 ) != ":" ))
{
text2.append(". ") ;
getline(cin, text) ;
}
else
{
getline(cin, text) ;
}
if (text == "")
{
cout << "End of session" << endl ; break ;
}
}
}
ofstream writer( filelocation.c_str() ) ;
if(! writer)
{
cout << "Error opening file for output: " << strerror(errno) << endl ;
return -1 ;
}
else
{
writer << text2 << endl ;
writer.close() ;
}
return 0 ;
}
Thanks for your help in advance!
"!" is a string, you want to compare against a character: '!'.
You can't compare "!" and '!'.
I suggest using rbegin() to address the last character:
text2.append(text.begin(), text.end());
switch(*text.rbegin())
{
case '!':
case '?':
case ':': text2.append(". "); break;
}
getline(cin, text);
if(text.empty())
{
cout << "End of session" << endl;
break;
}
if ((text.at(text.size() -1 ) != "!" ) && (text.at(text.size() -1 ) != "?") && (text.at(text.size() -1 ) != ":" ))
That is both inefficient and is not doing what you think. text.at(text.size() -1 ) returns the last character. To get what you want:
char lastChar = text[text.size() - 1]; // or char lastChar = *text.rbegin();
if (!(lastChar == '.' || lastChar == '?' || lastChar == '!')) // note the single quotes
{
text2.append(". ");
}
getline(cin, text);
Related
The Idea is to invoke a single function to check the user input and return True || False.
User Input with 0123456789 must return
The Number Entered Correctly
User Input with 0123w456789 must return
Number is not allowed or Contains invalid input such as "w"
User Input with 0123wx456789 must return
Number is not allowed or Contains invalid input such as "wx"
My Code:
#include <iostream>
using namespace std;
int main ( )
{
string i_numvalidation;
cout << "Enter the number: " << '\n';
cin >> i_numvalidation;
bool isNumber = true;
for (int i = 0; i < i_numvalidation.length(); i++)
{
if (!(i_numvalidation[i] >= '0' && i_numvalidation [i] <= '9'))
{
isNumber = false;
}
}
if (isNumber)
cout << " Entered number " << i_numvalidation << " is correct" << '\n';
else
cout << " Entered number " << i_numvalidation << " is not allowed or Contains invalid input such as " << "'\n";
}
Question is Updated to understand it clearly.
You already have almost everything you need to get the desired output. You only need to remember the characters that make the input invalid (ie those for which you set isNumber = false;) in a second string and print that instead of the original input. Really the only ingredient that you are not already using in your code is adding a character to a string and that can be done like this:
std::string x;
char invalid_character = 'w';
char other_invalid_character = 'p';
x += invalid_charater;
x += other_invalid_character;
std::cout << x; // prints wp
The Functions I have Implemented is working for a single value but it is still not printing the complete invalid characters.
If the Input is 0123ab456789 so it will print the error message with "a" instead of "ab". It must print "ab" as input contains "ab".
The Code:
#include <iostream>
using namespace std;
int main ( )
{
string i_numvalidation;
cout << "Enter the Number: " << '\n';
cin >> i_numvalidation;
bool isNumber = true;
int bad_index = 0 ;
if (i_numvalidation [0] == '0')
isNumber = false;
for (int i = 0; i < i_numvalidation.length () && isNumber; i++ )
{
if (!(i_numvalidation [i] >= '0' && i_numvalidation [i] <= '9'))
{
isNumber = false;
bad_index = i ;
break;
}
}
if (isNumber)
{
cout << " The Entered " << i_numvalidation << " number is correct" << '\n';
}
else
cout << " The Entered " << i_numvalidation << " is not allowed or Contains invalid input such as '" << i_numvalidation [ bad_index ] << "'\n";
}
Like:
String err='1';
for(int i=0;i<i_numvalidation.length(); i++)
{
if(i_numvalidation[i]!= '0' || i_numvalidation[i]!= '1' || i_numvalidation[i]!= '2' and so on...)
{
err[err.length()]=i_numvalidation[i];
isNumber=false;
}
}
if(!isNumber)
cout<<"That's not a number bruh"<<err<<endl;
Sorry if I'm not helpful, I tried...
Hope you'll get the answer.
I'm new to C++ and am finding it difficult to find information on the cin feature. This is my first program ever so it's very simple. It determines if the entered number is a prime number or composite whilst filtering out bad values such as negative numbers and decimals. The program also will time-out after 10 failed entries.
The last feature I want to add to this program is the ability to filter out character inputs but I'm having no luck with trying different solutions. I tried converting the character to a float/double/int but to no avail. I just need help with cin, if the user inputs the letter 'K' or any other invalid character i'd like the program to recognize this and then produce the "invalid value" cout message + new entry try x number of times.
Currently when a character is entered the program crashes and goes through all 10 try attempts at once leaving the output results in the terminal very sloppy.
#include <iostream>
#include <cmath>
using namespace std ;
int main (void)
{
//Declare variables
int y, c, i1 ;
double i ;
//Ask for user input
cout << endl << endl << "Please enter a number: " ;
cin >> i ;
//Eliminate bad user input values
i1 = i ;
//Detect when a decimal number is entered for the first attempt
for ( c = 1 ; int(i1) != i ; c ++ )
{
cout << endl << "This value is invalid. Please retry: " ;
cin >> i ;
i1 = i ;
//Terminate program after so many failed attempts
if ( 8 < c )
{
cout << endl << "This value is invalid. Try again next time! \n\n" ;
return 0 ;
}
//Detect if a '0' is entered on the latter attempts
for ( c ; i < 1 ; c ++ )
{
cout << endl << "This value is invalid. Please retry: " ;
cin >> i ;
i1 = i ;
//Terminate program after so many failed attempts
if ( 8 < c )
{
cout << endl << "This value is invalid. Try again next time! \n\n" ;
return 0 ;
}
}
}
//Detect when '0' is entered on the first attempt
for ( c = 1 ; i < 1 ; c ++ )
{
cout << endl << "This value is invalid. Please retry: " ;
cin >> i ;
i1 = i ;
//Terminate program after so many failed attempts
if ( 8 < c )
{
cout << endl << "This value is invalid. Try again next time! \n\n" ;
return 0 ;
}
//Detect if a decimal number is entered on the latter attempts
for ( c ; int(i1) != i ; c ++ )
{
cout << endl << "This value is invalid. Please retry: " ;
cin >> i ;
i1 = i ;
//Terminate program after so many failed attempts
if ( 8 < c )
{
cout << endl << "This value is invalid. Try again next time! \n\n" ;
return 0 ;
}
}
}
//Find prime numbers
for ( y = 1 ; y <= i ; y ++ )
{
//Give instant result if user input is no. 1
if ( i == 1 )
{
cout << endl << "The number: " << i << " is a composite number.\n\n" ;
break ;
}
//Eliminate no. 1 from prime number search
if ( y == 1 )
continue ;
//Search for a whole number division using modulus
if ( fmod(i, y) == 0 )
{
if ( i == y )
cout << endl << "The number: " << i << " is a prime number.\n\n" ;
else if ( i != y )
{
cout << endl << "The number: " << i << " is a composite number.\n\n" ;
break ;
}
}
}
return 0 ;
}
i was trying to find a way to check two different files and get, from the second, all lines that aren't in the first.. but does all the opposite.
I tried the possible to solve this but nothing...
This is the code:
int main(int argc, char *argv[])
{
setlocale(LC_ALL, "");
char username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserName(username, &username_len);
stringstream buffer;
buffer << "C:\\Users\\" << username << "\\Desktop\\";
stringstream buffer2;
buffer2 << "C:\\Users\\" << username << "\\Desktop\\Legit.txt";
stringstream buffer3;
buffer3 << "C:\\Users\\" << username << "\\Desktop\\Unlegit.txt";
stringstream buffer4;
buffer4 << "C:\\Users\\" << username << "\\Desktop\\result.txt";
string results = buffer4.str();
int offset;
int num;
num = 1;
string search;
string linea;
string legit;
string unlegit;
string line;
cout << "Is the Legit.txt file at '" << buffer.str() << "'? [Y/N]: ";
cin >> legit;
if (legit == "Y" || legit == "y"){
}else if(legit == "N" || legit == "n"){
return 0;
}else{
cout << "\n.";
return 0;
}
string legitfile = buffer2.str();
cout << "\nIs the Unlegit.txt file at '" << buffer.str() << "'? [Y/N]: ";
cin >> unlegit;
if (unlegit == "Y" || unlegit == "y"){
}else if(unlegit == "N" || unlegit == "n"){
return 0;
}else{
cout << "\n";
return 0;
}
string unlegitfile = buffer3.str();
ifstream file(legitfile.c_str());
if(file.is_open()){
while(getline(file, line)){
ifstream MyFile(unlegitfile.c_str());
if(MyFile.is_open()){
while(!MyFile.eof()){
getline(MyFile,linea);
if((offset = linea.find(line, 0)) != string::npos) {
cout << "\n[" << num << "]" << " Word Found: " << line << "\n";
num++;
fstream result(results.c_str());
result << line << "\n";
result.close();
}
}
MyFile.close();
}
}
file.close();
return 0;
}else{
cout << "\nThe file '" << legitfile << "' does not exist.";
cout << "\nThe file '" << unlegitfile << "' does not exist.";
}
}
As i said, This code checks which words are equals in both (first & second) files and, once found, writes them to a third file, there is a way to do the opposite (check the two files and get the words that aren't equals)? Thank you so much!
I'm new, both in the forum and in C++, sorry if I make any mistakes. (sorry for my bad english too).
The classic solution to this sort of problem is to use a hash table collection to represent all the words in the first file. Then while iterating items from the second file, consult the set constructed of the first file. In C++, the std::unordered_set will do fine.
#include <unordered_set>
using namespace std;
unordered_set<string> firstFileSet;
unordered_set<string> missingFromSecondFileSet;
string line;
while(!firstfile.eof())
{
getline(firstfile,line);
firstFileSet.insert(line);
}
Then for each word in the second file, use a second set collection to keep track of what words are missing.
while(!secondfile.eof())
{
getline(secondfile,line);
if (firstFileSet.find(line) != firstFileSet.end())
{
missingFromSecondFileSet.insert(line);
}
else
{
firstFileSet.erase(line);
}
}
After the above runs, firstFileSet contains all the lines in the first file that were not present in the second. missingFromSecondFileSet contains all the lines in the second file that were not in the first:
for (auto &s : firstFileSet)
{
cout << s << " was in the first file, but not the second" << endl;
}
for (auto &s : missingFromSecondFileSet)
{
cout << s << " was in the second file, but not the first" << endl;
}
There is a program called diff on linux which does just what you are looking to do in C++.
It is written in C so you can just copy its source code =P
for (;; cmp->file[0].buffered = cmp->file[1].buffered = 0)
{
/* Read a buffer's worth from both files. */
for (f = 0; f < 2; f++)
if (0 <= cmp->file[f].desc)
file_block_read (&cmp->file[f],
buffer_size - cmp->file[f].buffered);
/* If the buffers differ, the files differ. */
if (cmp->file[0].buffered != cmp->file[1].buffered
|| memcmp (cmp->file[0].buffer,
cmp->file[1].buffer,
cmp->file[0].buffered))
{
changes = 1;
break;
}
/* If we reach end of file, the files are the same. */
if (cmp->file[0].buffered != buffer_size)
{
changes = 0;
break;
}
}
Taken from ftp://mirrors.kernel.org/gnu/diffutils/diffutils-3.0.tar.gz > src/analyze.c
I have a relatively large program and not all of it is relating to my question, but this particular bit is stumping me.
Below is my int main:
int main ()
{
int caseNumber ;
string clientName, clientEmail, subject, path, fileName, firstTime ;
//creates string for path of files created and where the Python project is stored (with the .exe)
path = _pgmptr ;
fileName = "EmailGenerator.exe" ;
fileName.length() ;
path.erase(path.length() - fileName.length()) ;
//checks first time use for customizing
cout << "Welcome to the Ticket Email Generator.\n\n"
<< "If this is your first time using this program,\nplease enter Y to customize some personal details.\n"
<< "If not, enter any other character.\n" ;
cin >> firstTime ;
cin.ignore() ;
if (firstTime == "Y" || firstTime == "y")
{
//save sender email (defaults to morgan_wallace#cable.comcast.com - creator)
setSender (path) ;
//Verifies signature file is as desired (to be saved for the future)
char ready = 'n' ;
while (!(ready == 'y' || ready == 'Y'))
{
std::cout << "\nPlease modify the signature.txt file located in " + path << endl
<< "Enter Y when done.\n" ;
cin >> ready ;
cin.ignore() ;
}
}
//Email "To" field:
setTo (path) ;
//Email "Subject" field:
setSubject (path) ;
//Email "Body" field:
std::cout << "\nPlease provide the following information for the body of the email:" << endl ;
//create standard time-based greeting at top of message
setToName (path) ;
//select message type & compose body of message
ofstream scriptfout (path + "script.txt") ;
std::cout << "\nPlease select from case type menu:" << endl << endl ;
caseTypeMenu(scriptfout) ;
scriptfout.close() ;
//compose full body and add signature
setBody (path) ;
std::cout << "Would you like to review your email before sending? Y/N " ;
char reviewChar ;
cin >> reviewChar ;
cin.ignore() ;
if (reviewChar == 'y' || reviewChar == 'Y')
{
review (path) ;
}
else if (reviewChar == 'N' || reviewChar == 'n')
{
//run email sender (python program)
string pythonPathString = path + "EmailProj/EmailProj/EmailProj.py" ;
string pythonString = "C:/Python27/python.exe " + pythonPathString + " " + path ;
system(pythonString.c_str()) ;
//Exit program
string anything ;
std::cout << "Enter anything to exit\n" ;
cin >> anything ;
cin.ignore() ;
}
else
{
cout << "Invalid entry review: " + reviewChar << endl ;
//Exit program
string anything ;
std::cout << "Enter anything to exit\n" ;
cin >> anything ;
cin.ignore() ;
}
return 0 ;
}
My specific issue my last if/else (everything else executes as expected):
std::cout << "Would you like to review your email before sending? Y/N " ;
char reviewChar ;
cin >> reviewChar ;
cin.ignore() ;
if (reviewChar == 'y' || reviewChar == 'Y')
{
review (path) ;
}
else if (reviewChar == 'N' || reviewChar == 'n')
{
//run email sender (python program)
string pythonPathString = path + "EmailProj/EmailProj/EmailProj.py" ;
string pythonString = "C:/Python27/python.exe " + pythonPathString + " " + path ;
system(pythonString.c_str()) ;
//Exit program
string anything ;
std::cout << "Enter anything to exit\n" ;
cin >> anything ;
cin.ignore() ;
}
else
{
cout << "Invalid entry review: " + reviewChar << endl ;
//Exit program
string anything ;
std::cout << "Enter anything to exit\n" ;
cin >> anything ;
cin.ignore() ;
}
If you input an 'h', or some character not Y, y, N, or n, it does not print the error script with the inappropriate answer. It prints a line of my code (something that is printed to screen with cout in an earlier portion of the code) and then "Enter anything to exit" and waits for input. If you input 'g', it just skips the error message altogether and prints the "Enter anything to exit line" and waits for input.
The point of this last if/else is to allow the user to view their message, and then decide whether to send it, edit portions of it, or just disregard it completely. For purposes of error checking, I would like to handle inputs that are not Y, y, N, and n, even though theoretically there should be no other inputs.
Your problem is here:
cout << "Invalid entry review: " + reviewChar << endl ;
When you use the plus sign you are actually adding the value of an integer to a pointer, not concatenating strings.
Try with this:
cout << "Invalid entry review: " << reviewChar << endl ;
This bit of code works. I can also copy paste from start to end several times inside my main and it will still work.
int main()
{
string str;
cout << "Input a palindrome: "; // Start
getline(cin, str);
if (testPalindrome(str) == 1)
cout << "Your input is a palindrome: True" << endl;
else
cout << "Your input is a palindrome: False" << endl;
cout << endl; // End
cout << "\nCreated by,\nNorman Ettedgui" << endl;
system("pause");
return 0;
}
However this bit of code will not work and the error I get is a strings out of bound within my function (oddly enough before the function call).
This is my testPalindrome function:
bool testPalindrome(string str)
{
string newStr;
for (int i = 1; i < str.length() - 1; i++)
newStr += str[i];
if (newStr.length() > 1)
testPalindrome(newStr);
if (str[0] == str[str.length() - 1])
return true;
}
This is what I'm trying to run:
int main()
{
string str;
int i = 0;
while (i != -1)
{
cout << "Input a palindrome: ";
getline(cin, str);
if (testPalindrome(str) == 1)
cout << "Your input is a palindrome: True" << endl;
else
cout << "Your input is a palindrome: False" << endl;
cout << "-1 to Exit or any other number to continue: ";
cin >> i;
cout << endl;
}
cout << "\nCreated by,\nNorman Ettedgui" << endl;
system("pause");
return 0;
}
Try the following function
bool testPalindrome( string s)
{
return ( s.size() < 2 ? true
: s.front() == s.back() && testPalindrome( s.substr( 1, s.size() -2 ) ) );
}
Also in main substitute this statement
if (testPalindrome(str) == 1)
for
if ( testPalindrome(str) )
If you use getline and operator >> simultaneously then you should use ignore to skip ENTER key
(DO not forget include <limits>)
#include <limits>
while (i != -1)
{
cout << "Input a palindrome: ";
cin.ignore( numeric_limits<streamsize>::max() );
getline(cin, str);
//...
cin >> i;
cout << endl;
}
I will explain you why you got the error. Without statement with the call of ignore function getline read an empty string. So str was empty. In function testPalindrome there is statement
for (int i = 1; i < str.length() - 1; i++)
As for an empty string its length is equal to 0 then expression
str.length() - 1
has the maximum value for the unsigned type because the type of this expression is some unsigned integral type and the internal representation of -1 corresponds to the maximim unsigned value.
So variable i will be always less than -1 and you get memory access violation.
Also I would use another loop without using additional variable i.
while ( true )
{
cout << "Input a palindrome: ";
string str;
getline(cin, str);
if ( str.empty() ) break;
//...
}
if (newStr.length()>1) only handles the condition when newStr.length() is >1. You need an else statement to handle when the condition: if (newStr.length()>1) is false.