how to force user to input exactly 8 characters into string - c++

how can I limit a user to input 8 characters into string?
can something like this work?
string MyString;
getline(std::cin, MyString, 8);
or maybe there is a different idea to accomplish it
thanks in advance
clarification:
I want to enable the user to input up to 8 characters in the string, but he may enter less.

You can use a loop..
while (MyString.length() != 8) {
std::cout << "Enter exactly 8 characters:";
getline(std::cin, MyString);
}

its hard to think this will help considering my experience (1mnth!)
at codecademy.com in the "Python" language one might say something like:
my_string = "jackie"
len(my_string)
#would print 5
if my_string is <= ..... # if my string is greater or equal to print the following
print "name is too long "
Hope that generated something other than disgust
sincerely dedicated noobie

There is a difference between requesting 8 characters from the User and preventing the User from entering more than 8.
Requesting 8 from User
You can request 8 characters from the User, but the User is allowed to enter as many characters as the User wants until a newline character is entered. This is the behavior of the standard console input.
The console has buffered the all the characters. Depending on the extraction method, you will be extracting 8 characters from the input buffer into your variable. The remaining characters are still in the buffer.
Preventing User from entering more than 8
This is typically used in entering passwords. The standard C++ input facilities cannot help here.
You will need platform specific control of the input source. You will need to read each character, test for a newline and optionally echo back either the character, a uniform character like '*', or not display any characters.
Since it is platform specific, look up the API for your platform.

#include <iostream>
#include <string>
int main(){
std::string str;
bool cStr = true; //check string
while (cStr){
std::getline(std::cin, str);
if (str.size() <= 8) cStr = false;
}
}
You can add a bool object to test your string using an if-statement. If the string size is less than or equal to 8, it will then advert the bool statement to false allowing the exit of the while loop.

Related

String.length() shows incorrect value [duplicate]

This question already has answers here:
Read whole ASCII file into C++ std::string [duplicate]
(9 answers)
Closed 3 years ago.
I am trying this following code in cpp
#include <iostream>
#include <string>
void Strlength(const string& s) {
cout << s.length() << endl;
}
int main() {
string s;
cin >> s;
cout << s.length() << endl;
Strlength(s);
return 0;
}
The string which I am giving as input is 100,000 characters long and is like "xxxxxxx...xxxxabcde"(fill the ... with remaining x)
This gives me the output as
4095
4095
I am expecting the output to be 100000. what am I doing wrong?
This relates to one of the hackerrank problem (Test case 10): String Similarity
Assuming you describe the input correctly, that is it is one single "word", then the issue is not in your code. The issue must be in the environment which runs the code. It has some kind of mechanism to feed the standard input to your program. Either that has a limitation on total input length, or it has a limitation of line length. 4 kilobytes is 4096 bytes, so perhaps your input is limited by that: 4095 chars of the word plus a newline character (or terminating 0 byte of string, or whatever).
If you are running this under some kind of web interface in browser, the problem could even be, that the input field in the web page has that limitation.
If you need to dig into this, try to read char by char and see what you get, how many chars and how many newlines. Also examine cin.fail(), cin.eof(), cin.bad() and cin.good(). For the question code, you should expect failbit to be false, and eofbit might be true oe false depending on how the input was truncated.

C++ using cin.ignore() to remove first non-int from the input stream [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
So For example if I input:
33a
and I want to remove "a" from the stream and store 33 into an int, how to do this using cin.ignore?
Edits:
To be more precise:so If I have input:
2
3
4a
b
or
2
3
4
a
b
I want to store those 2,3,4 into an array, and also when encountered 'a'(first non-int char), ignore 'a', and then jumped out the input reading loop(ie
while(cin>>num)
)?
TL;DR version based on question edit:
The smart way is to use a std::vector to store the read values and ignore all the messiness of an array of unknown size.
Then
while not done
read a value
if value successfully read
store value
ignore to the end of the line
else
clear stream error
ignore to the end of the line
I'm only providing a pseudocode answer because this looks too much like a homework assignment at this point. All of the required bits and pieces are discussed below and it's up to OP to assemble them correctly.
If you MUST use an array, before storing a value test to make sure you will not overrun the end of the array by storing the value.
Old answer:
Link to documentation.
cin.ignore() ignores one character.
cin.ignore(10) ignores up to 10 characters.
cin.ignore(10, ' ') ignores up to 10 characters or it finds and consumes a space.
Another common case is discarding the rest of the line: cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
So...
int val;
cin >>val;
cin.ignore();
will handle the simple case of reading an int and discarding the next character. Input of "33a" will result in 33 being stored in val, 'a' being ignored, and the end of line (enter keypress) used to trigger this chain of events is left in cin for future consumption. This could be a problem so,
int val;
cin >>val;
cin.ignore((std::numeric_limits<std::streamsize>::max(), '\n');
will read 33 into val, discard 'a` and anything else the user typed in. This may not be what you want. For example, input of "33a 44b"
int val;
cin >>val;
cin.ignore((std::numeric_limits<std::streamsize>::max(), ' ');
will read 33 into val, discard 'a' and anything else the user typed in up to the first space. Another pass through the above code will result in 44 in val, the discard of 'b', and the end of line staying in cin.
Attempting to use std::getline at this point is bad. It will instantly consume the end of line and return an empty string. However, a third pass though the above code will discard the end of line as whitespace and wait for more input from the user.
However users are lousy sources of input, so you want to protect cin >>val; from a user typing in something like "blah", hitting enter, and trying again. "blah cannot convert to an int, so cin will be set into the error state and you need to acknowledge this before continuing.
int val;
while (!(cin >>val)) // continue as long as the user has finger trouble
{
cin.clear() // clear the error state
// discard the rest of the line because who knows what other garbage is on it.
cin.ignore((std::numeric_limits<std::streamsize>::max(), '\n');
// probably want to notify the user and prompt for good input here.
}
//whichever ignore code fits your usecase
or similar will handle the bad input case.
Although it's not immediately obvious now to do it, streams actually incorporate a way to deal with this quite directly (at least assuming I've understood the question correctly).
When you read (for example) a number from a stream, the stream skips any white-space before the number. To figure out whether a character is white-space or not, the stream uses an associated locale--specifically, the locale's ctype facet.
To have the stream ignore everything except digits, we can provide a locale that classifies everything except digits as white space.
#include <locale>
#include <iostream>
#include <algorithm>
#include <vector>
#include <sstream>
#include <iterator>
class my_ctype : public std::ctype<char> {
public:
mask const *get_table() {
static std::vector<std::ctype<char>::mask>
table(table_size, (mask)space);
std::fill_n(table.begin() + '0', 10, (mask)digit);
return &table[0];
}
my_ctype(size_t refs=0) : std::ctype<char>(get_table(), false, refs) { }
};
int main() {
std::istringstream s("1 2, 9 3 a 4b 2 5");
s.imbue(std::locale(std::locale(), new my_ctype));
int i;
while (s >> i)
std::cout << i << "\n";
}
Result:
1
2
9
3
4
2
5
Note that with this, we don't have to use ignore (or anything else, except the normal stream extractor) to ignore the garbage we don't care about in the stream. The other side of this is that this is useful (at least primarily) when assigned to the stream as a whole. If you want to read 4 numbers this way, then be able to go back to reading everything normally, this probably won't be a useful technique for your situation.

Line Breaks when reading an input file by character in C++

Ok, just to be up front, this IS homework, but it isn't due for another week, and I'm not entirely sure the final details of the assignment. Long story short, without knowing what concepts he'll introduce in class, I decided to take a crack at the assignment, but I've run into a problem. Part of what I need to do for the homework is read individual characters from an input file, and then, given the character's position within its containing word, repeat the character across the screen. The problem I'm having is, the words in the text file are single words, each on a different line in the file. Since I'm not sure we'll get to use <string> for this assignment, I was wondering if there is any way to identify the end of the line without using <string>.
Right now, I'm using a simple ifstream fin; to pull the chars out. I just can't figure out how to get it to recognize the end of one word and the beginning of another. For the sake of including code, the following is all that I've got so far. I was hoping it would display some sort of endl character, but it just prints all the words out run together style.
ifstream fin;
char charIn;
fin.open("Animals.dat");
fin >> charIn;
while(!fin.eof()){
cout << charIn;
fin >> charIn;
}
A few things I forgot to include originally:
I must process each character as it is input (my loop to print it out needs to run before I read in the next char and increase my counter). Also, the length of the words in 'Animals.dat' vary which keeps me from being able to just set a number of iterations. We also haven't covered fin.get() or .getline() so those are off limits as well.
Honestly, I can't imagine this is impossible, but given the restraints, if it is, I'm not too upset. I mostly thought it was a fun problem to sit on for a while.
Why not use an array of chars? You can try it as follow:
#define MAX_WORD_NUM 20
#define MAX_STR_LEN 40 //I think 40 is big enough to hold one word.
char words[MAX_WROD_NUM][MAX_STR_LEN];
Then you can input a word to the words.
cin >> words[i];
The >> operator ignores whitespace, so you'll never get the newline character. You can use c-strings (arrays of characters) even if the <string> class is not allowed:
ifstream fin;
char animal[64];
fin.open("Animals.dat");
while(fin >> animal) {
cout << animal << endl;
}
When reading characters from a c-string (which is what animal is above), the last character is always 0, sometimes represented '\0' or NULL. This is what you check for when iterating over characters in a word. For example:
c = animal[0];
for(int i = 1; c != 0 && i < 64; i++)
{
// do something with c
c = animal[i];
}

c++ change space to enter

I don't know if this is even possible.
I have an assignment to translate words and phrases into pig Latin in C++. the fastest way to do this would be to have the user hit enter after each word, but this would make entering a continuous phrase impossible without hitting enter instead of the space bar.
your
text
would
be
entered
like
this
The your output could easily be:
youway exttay ouldway ebay enteredway ikelay histay
But still putting the info in would be weird.
Instead I would like to force the program to treat the space bar as though it were the enter key (carriage return).
your text would be entered like this
That way each word would enter my array separately from the string, the user only having to hit enter 1 time.
You could do something like:
Read a line of text from user input (which may have multiple words)
Split the line into words
Translate each word into Pig Latin
Print the words out with spaces between them
Rather than thinking of this in terms of "how can I change these keys to mean something else", think of it in terms of "how can I best work with what the user is expecting to type". If the user is expecting to type spaces between words (makes sense), then design your program so that it can handle that kind of input.
You can have the user input data as a single line, since that seems natural.
If you want some help in parsing the words to operate on the one at a time, then try this other question.
Here's the cheap-o way to do it:
std::string in;
while (std::cin >> in)
std::cout << piglatin(in) << char(std::cin.get());
std::cin >> in skips any leading whitespace in the input stream, and then fills in with the next whitespace-terminated word from the input stream, leaving the whitespace termination in the input stream. char(std::cin.get()) then extracts that terminator (which might be a space or a new line). The while loop is terminated by an end-of-file.
You can use that provided you understand it.
Added:
Here's a better way to find whether the word read was terminated with a space or a new-line:
#include <cctype>
char look_for_nl(std::istream& is) {
for (char d = is.get(); is; d = is.get()) {
if (d == '\n') return d;
if (!isspace(d)) {
is.putback(d);
return ' ';
}
}
// We got an eof and there was no NL character. We'll pretend we saw one
return '\n';
}
Now the hack looks like this:
std::string in;
while (std::cin >> in)
std::cout << piglatin(in) << look_for_nl(std::cin);

How to check the length of an input? (C++)

I have a program that allows the user to enter a level number, and then it plays that level:
char lvlinput[4];
std::cin.getline(lvlinput, 4)
char param_str[20] = "levelplayer.exe "
strcat_s(param_str, 20, lvlinput);
system(param_str);
And the level data is stored in folders \001, \002, \003, etc., etc. However, I have no way of telling whether the user entered three digits, ie: 1, 01, or 001. And all of the folders are listed as three digit numbers. I can't just check the length of the lvlinput string because it's an array, so How could I make sure the user entered three digits?
Why not use std::string?
This makes storage, concatenation, and modification much easier.
If you need a c-style string after, use: my_string.c_str()
Here is a hint: To make your input 3 characters long, use std::insert to prefix your number with 0's.
You are really asking the wrong question. Investigate the C++ std::string class and then come back here.
Eh? Why do they need to enter 3 digits? Why not just pad it if they don't? If you really want to check that they entered 3 digits, use strlen. But what I recommend you do is atoi their input, and then sprintf(cmd, "levelplayer.exe %03d", lvlinput_as_integer)
Here's how you could do this in C++:
std::string lvlinput;
std::getline(std::cin, lvlinput);
if (lvlinput.size() > 3) { // if the input is too long, there's nothing we can do
throw std::exception("input string too long");
}
while (lvlinput.size() < 3) { // if it is too short, we can fix it by prepending zeroes
lvlinput = "0" + lvlinput;
}
std::string param_str = "levelplayer.exe ";
param_str += lvlinput;
system(param_str.c_str());
You've got a nice string class which takes care of concatenation, length and all those other fiddly things for you. So use it.
Note that I use std::getline instead of cin.getline. The latter writes the input to a char array, while the former writes to a proper string.
What do you mean you can't check the length of the string? getline generates a NULL terminated c-string so just use strlen(lvlinput).
Neil told you where you should start, your code might look like this.
std::string level, game = "levelplayer.exe ";
std::cout << "Enter the level number : ";
std::cin >> level;
if(level.size() != 3)
{
// Error!
}
else
{
// if you have more processing, it goes here :)
game += level;
std::system(game.c_str());
}
You can check the length of your NULL terminated string that getline returns by using:
int len = strlen(lvlinput);
This works because getline returns a NULL-terminated string.
However, this is besides the point to your problem. If you want to stay away from std::string (and there isn't any particular reason why you should in this case), then you should just convert the string to an integer, and use the integer to construct the command that goes to the system file:
char lvlinput[4];
std::cincin.getline(lvlinput, 4);
char param_str[20];
snprintf(param_str, 20, "levelplayer.exe %03d", atoi(lvlinput));
system(param_str);