A string is a variable-length sequence of characters. Why does it receive anything and prints it out?
#include <iostream>
#include <string>
using namespace std;
int main (){
string word;
while (cin >> word){
cout << word << endl;
}
return 0;
}
In this program, we read into a string, not an int. How can I fall out of this while loop i.e hit an invalid input?
Reading into a string will not fail, all input is valid. You may add any validation you like once the string is read.
Your question is a little vague, but if you're asking how to end the loop you can do it with an end-of-file. On Linux this you can generate one from the console with Control-D, and on Windows with Control-Z plus Enter.
Because you are taking the input in a string and string is a sequence of characters .so it takes anything you input from the keyboard either it is number or alphabet or any special character .
How can I check for invalid input?
If you could define what you consider to be "invalid input" you can filter for it in one of the std::string helper methods. In your example you eluded to numbers not being strings... so if you want to do something with pure numbers...
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main (){
string word;
while (cin >> word){
bool isNumber = (word.find_first_not_of("0123456789") == std::string::npos);
if (isNumber){
cout << "it's a number! " << word << endl;
}else{
cout << word << endl;
}
}
return 0;
}
Related
My program is largely incomplete, but I assumed that using toupper to modify the strings following their input from the textfile would work to change all the characters of said string to uppercase. I read that works with type int, or what I assume is Ascii in this case. But I'm not really sure where to go from here. What is the most efficient means of converting and checking strings from a textfile as far as beginner C++ goes?
I've googled this issue and found a wide variety of ways, such as using std::transform, but I feel like my instructor would only want us using methods taught from our book 'Starting out with C++' by Tony Gaddis. Unfortunately I'm not finding any reference in my book where toupper is being used on textfile input, only on char values. For education's sake I'm hoping you have an idea of what I should be using here and why. I welcome recommended reading.
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
string text;
ifstream textFile;
int ch;
textFile.open("letter_count.txt", ios::in);
toupper(textFile.get());
isalpha(textFile.get());
if (textFile)
{
// Read an item from the file.
getline(textFile, text);
// While the last read operation
// was successful, continue.
while (textFile)
{
if (textFile)
// Display the last item read.
cout << text << endl;
// Read the next item.
getline(textFile, text);
}
// Close the file.
textFile.close();
}
else
{
cout << "ERROR: Cannot open file. \n";
}
cout << "The most common letter is " " with " " occurances. \n";
cout << "The least common letter is " " with " " occurances. \n";
system("pause");
}
I'm getting no results from using toupper.
That is because toupper takes only one int value. Notice here:
http://www.cplusplus.com/reference/cctype/toupper/?kw=toupper
You have to loop over every char in your string in order to convert it.
Idea:
I'm trying to create a program that searches for user-entered-word in a .txt file. Size of the word is not given. I want to find a way to dynamically store user's word to be able to compare it to the other words from file.
The entire program is huge so i only attach a part related to my queasions.
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
void vectorfill(vector<char>& newword) //filling char vector
{
char input;
scanf_s("%c", &input);
while (input != -1)
{
newword.push_back(input);
scanf_s("%c", &input);
}
}
int main (void)
{
vector<char> word;
printf("Enter a word: (-1 to finish)");
vectorfill(word);
}
Questions:
1) Is char vector a best idea in this case ?
2) (In case we're good with char vector)How to make compiller understand that user finished writing their word? Can we ask him to put (-1) at the end? Is there a better way to mark the end of the input?
1> No. Use a std::string
2> Yes. Use whitespace.
Example:
#include <iostream>
#include <string>
int main ()
{
std::string word;
std::cout << "Enter a word" << std::endl;
std::cin >> word;
// do something with word. For example,
std::cout << "You entered" << word << '\n';
}
As soon as the user types in at least one number, letter, or other non-whitespace character followed by a whitespace character a word will have been captured in word. If you have special requirements like this word can only contain letters (no numbers, bells, ASCII art characters, etc...) a simple loop with isalpha can sort that out in a few lines of code, but not as few as std::find_if and isalpha.
If the searching content is in txt file. Using std::vector<std::string> may be better. You can use the split char to split the words.
If the content is from user's keyboard input. you can also use std::string to store every word typed, and store it in std::vector<std::string>. Just like this:
std::string s;
std::vector<std::string> vec;
std::cout << "Please enter somestring" << std::endl;
while (cin >> s)
{
vec.push_back(s);
cout << "You have entered : " << s << endl;
}
#include <iostream>
#include <string>
using namespace std;
int main()
{
int num;
cin >> num;
string s;
getline(cin, s);
cout << s << " " << num << endl;
return 0;
}
In this code if I input 3 and press enter, then s takes an empty string.
1) If it is taking the first character as a newline, then is there a possible solution of taking line as input after taking an integer as input?
2) If my input is 4567artyu then how it is deciding whether 7 has to go into the s or num ?
I recommend that you always read complete lines of input from your users. It will cause the least confusion.
Ask for input.
Use std::getline to read a line of input.
If you don't want a string but, say, an integer, use std::stoi or (more general) boost::lexical_cast to safely convert the input to your desired target type. This is where you catch poor inputs and complain at the user.
I don't think that many users, if prompted for a number, would expect that entering 42bananas would be accepted as 42 and the bananas part be “remembered” for later. It will most likely be a typo and the user will be happy to be asked to correct it.
For taking line as input after taking integer as input you can consider removing the stray '\n' character from the stream.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int num;
cin >> num;
getchar();
string s;
getline(cin, s);
cout << s << " " << num << endl;
return 0;
}
This will do the trick.
For second question, it reads 4567 as integer, it will continue to read it as integer until limit of int is reached and if limit is reached it will not consider anything after that. Then it will put the maximum value of int in the variable num and null int the string s. If limit is not reached, then string will remain in the input stream as it is, and will be fetched by variable s.
Try using cin.clear before you accept string
I have a C++ program which needs to take user input. The user input will either be two ints (for example: 1 3) or it will be a char (for example: s).
I know I can get the twos ints like this:
cin >> x >> y;
But how do I go about getting the value of the cin if a char is input instead? I know cin.fail() will be called but when I call cin.get(), it does not retrieve the character that was input.
Thanks for the help!
Use std::getline to read the input into a string, then use std::istringstream to parse the values out.
You can do this in c++11. This solution is robust, will ignore spaces.
This is compiled with clang++-libc++ in ubuntu 13.10. Note that gcc doesn't have a full regex implementation yet, but you could use Boost.Regex as an alternative.
EDIT: Added negative numbers handling.
#include <regex>
#include <iostream>
#include <string>
#include <utility>
using namespace std;
int main() {
regex pattern(R"(\s*(-?\d+)\s+(-?\d+)\s*|\s*([[:alpha:]])\s*)");
string input;
smatch match;
char a_char;
pair<int, int> two_ints;
while (getline(cin, input)) {
if (regex_match(input, match, pattern)) {
if (match[3].matched) {
cout << match[3] << endl;
a_char = match[3].str()[0];
}
else {
cout << match[1] << " " << match[2] << endl;
two_ints = {stoi(match[1]), stoi(match[2])};
}
}
}
}
I'm obviously not quite getting the 'end-of-file' concept with C++ as the below program just isn't getting past the "while (cin >> x)" step. Whenever I run it from the command line it just sits there mocking me.
Searching through SO and other places gives a lot of mention to hitting ctrl-z then hitting enter to put through an end-of-file character on windows, but that doesn't seem to be working for me. That makes me assume my problem is elsewhere. Maybe defining x as a string is my mistake? Any suggestions about where I'm going wrong here would be great.
Note: sorry for the lack of comments in the code - the program itself is supposed to take in a series of
words and then spit back out the count for each word.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iomanip>
using std::cin;
using std::cout; using std::endl;
using std::sort;
using std::string; using std::vector;
int main()
{
cout << "Enter a series of words separated by spaces, "
"followed by end-of-file: ";
vector<string> wordList;
string x;
while (cin >> x)
wordList.push_back(x);
typedef vector<string>::size_type vec_sz;
vec_sz size = wordList.size();
if (size == 0) {
cout << endl << "This list appears empty. "
"Please try again." << endl;
return 1;
}
sort(wordList.begin(), wordList.end());
cout << "Your word count is as follows:" << endl;
int wordCount = 1;
for (int i = 0; i != size; i++) {
if (wordList[i] == wordList[i+1]) {
wordCount++;
}
else {
cout << wordList[i] << " " << wordCount << endl;
wordCount = 1;
}
}
return 0;
}
If you're on windows ^Z has to come as the first character after a newline, if you're on a unixy shell then you want to type ^D.
The input portion of your code works. The only real problem I see is with the loop the tries to count up the words:
for (int i = 0; i != size; i++) {
if (wordList[i] == wordList[i+1]) {
The valid subscripts for wordList run from 0 through size-1. In the last iteration of your loop, i=size-1, but then you try to use wordList[i+1], indexing beyond the end of the vector and getting undefined results. If you used wordList.at(i+1) instead, it would throw an exception, quickly telling you more about the problem.
My guess is that what's happening is that you're hitting Control-Z, and it's exiting the input loop, but crashing when it tries to count the words, so when you fix that things will work better in general. If you really can't get past the input loop after fixing the other problem(s?), and you're running under Windows, you might try using F6 instead of entering control-Z -- it seems to be a bit more dependable.
I pretty much always use getline when using cin (particularly when what I want is a string):
istream& std::getline( istream& is, string& s );
So, you'd call getline(cin, x) and it would grab everything up to the newline. You have to wait for the newline for cin to give you anything anyway. So, in that case, your loop would become:
while(getline(cin, x))
wordList.push_back(x);
cin does not accept blank space or line breaks so execution of cin does not complete unless you enter something , here is a test program that gives you what you want
#include "stdafx.h"
#include<iostream>
#include <string>
#include <sstream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string str = "";
while(std::getline(cin, str) && str!="")
{
cout<<"got "<<str<<endl;
}
cout<<"out"<<endl;
cin>>str;
return 0;
}