c++ change space to enter - c++

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);

Related

Detect a newline character with getline or istringstream

In my program, I'm asking the user for input via getline, and then in a separate class, splitting the string into three different strings which I will then check via a list of pre-determined values.
The way it works now, if someone enters an invalid command, I display "INVALID"
The problem I'm having is with a string containing only spaces or only a single newline character.
Here is what I'm trying to do:
std::string command; // command user enters
getline(std::cin, command); // user input here
std::string tempCheck; // if we have a value in here other than empty, invalid
// use istringstream to grab the words, max of 3
std::istringstream parse{fullCommand}; // parse command into words
if(fullCommand.empty()){ // nothing has been input
std::cout << "INVALID" << std::endl;
return;
}
parse >> command; // stores first word (the command)
parse >> actionOne; // stores second word as parameter
parse >> actionTwo; // stores third word as parameter
parse >> tempCheck;
if(!tempCheck.empty()) {
std::cout << "INVALID" << std::endl;
return;
}
The variable tempCheck basically means that if it goes over three words (the limit I want for commands), then it is INVALID. I also thought that having an empty string would work, but it just ends up in an infinite loop when nothing is input, but I just hit enter.
Here is what I expect my input to be doing (bold is output):
CREATE username password
**CREATED**
LOGIN username password
**SUCCEEDED**
ASDF lol lol
**INVALID**
**INVALID**
REMOVE username
**REMOVED**
**INVALID**
QUIT
**GOODBYE**
Here is what is happening:
CREATE username password
**CREATED**
// newline entered here
And it goes into a seemingly infinite loop. I can still type things, however, they don't actually affect anything. For example typing QUIT does nothing. But, if I restart my program and just type "QUIT" without trying to only use a newline character or only use a space, I get the expected output:
QUIT
**GOODBYE**
So, how do I tell either getline, or my istringstream, that if a user just enters a bunch of spaces and then hits enter, OR if the user just hits enter, display invalid and return? And is there anyway to do this with just getline or istringstream?
Alex, the following code may be helpful:
std::string strip(std::string const& s, std::string const& white=" \t\n")
{
std::string::size_type const first = s.find_first_not_of(white);
return (first == std::string::npos)
? std::string()
: s.substr(first, s.find_last_not_of(white)-first+1);
}
You may apply it before creating the istringstream:
std::istringstream parse{strip(fullCommand)};
The above code was borrowed and slightly modified from the old well-known technique.

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];
}

Detecting space in a file in c++

Hi i was just wondering if anybody could help me i am reading characters from a file then inserting them into a map i have the code working i was just wondering how do i detect if a space is in the file cause i need to store the amount of times a space occurred in a file any help would be great thanks.
map<char, int> treeNodes; //character and the frequency
ifstream text("test.txt");
while(!text.eof())
{
text >> characters;
//getline(text,characters);
cout << characters;
if(treeNodes.count(characters) == 0)
{
if(isspace (characters))
{
cout << "space" << endl;
}
else
treeNodes.insert(pair<char,int>(characters,1));
}
else
{
treeNodes[characters] += 1;
}
}
Formatted input, i.e. when using the right shift operator>>() skips leading whitespace by default. You can turn this off using std::noskipws but depending on what sort of things you want to read it won't be a very happy experience. The best approach is probably using unformatted input, i.e. something like std::getline() and split the line on space within the program.
If you just want to count the number of times any particular character occurred, you probably want to use std::istreambuf_iterator<char> and just iterate over the content of the stream (this code also omits some other unnecessary clutter):
for (std::istreambuf_iterator<char> it(text), end(); it != end; ++it) {
++treeNodes[*it];
}
BTW, you never want to use the result of eof() for something different than determining whether the last read failed because the stream has reached its end.
couldn't you just cast the char to an int and test if it is equal to the ascii value of a space?

C++: Why does space always terminate a string when read?

Using type std::string to accept a sentence, for practice (I haven't worked with strings in C++ much) I'm checking if a character is a vowel or not. I got this:
for(i = 0; i <= analyse.length(); i++) {
if(analyse[i] == 'a' || analyse[i] == 'e' [..etc..]) {
...vowels++;
} else { ...
...consonants++;
}
This works fine if the string is all one word, but the second I add a space (IE: aeio aatest) it will only count the first block and count the space as a consonant, and quit reading the sentence (exiting the for loop or something).
Does a space count as no character == null? Or some oddity with std::string?, It would be helpful to know why that is happening!
EDIT:
I'm simply accepting the string through std::cin, such as:
std::string analyse = "";
std::cin >> analyse;
I'd guess you're reading your string with something like your_stream >> your_string;. Operator >> for strings is defined to work (about) the same as scanf's %s conversion, which reads up until it encounters whitespace -- therefore, operator>> does the same.
You can read an entire line of input instead with std::getline. You might also want to look at an answer I posted to a previous question (provides some alternatives to std::getline).
I can't tell from the code that you have pasted, but I'm going to go out on a limb and guess that you're reading into the string using the stream extraction operator (stream >> string).
The stream extraction operator stops when it encounters whitespace.
If this isn't what's going on, can you show us how you're populating your string, and what its contents are?
If I'm right, then you're going to want a different method of reading content into the string. std::getline() is probably the easiest method of reading from a file. It stops at newlines instead of at whitespace.
Edit based on edited question:
use this (doublecheck the syntax. I'm not in front of my compiler.):
std::getline(std::cin, analyze);
This ought to stop reading when you press "enter".
If you want to read in an entire line (including the blanks) then you should read using getline. Schematically it looks like this:
#include <string>
istream& std::getline( istream& is, string& s );
To read the whole line you do something like this:
string s;
getline( cin, s );
cout << "You entered " << s << endl;
PS: the word is "consonant", not "consenent".
The >> operator on an istream separates strings on whitespace. If you want to get a whole line, you can use readline(cin,destination_string).

functionality of cin in c++

I'm a bit confused by the results of the following function:
int main() {
string command;
while(1) {
cin >> command;
if(command == "end")
return 0;
else
cout << "Could you repeat the command?" << endl;
}
return 0;
}
First of all - the output line ("could you...") repeats once for each individual word in the input (stored in command). So far as I can see, it should only be possible for it to happen once for each instance of the loop.
Also, when the line 'if(command == "end")' is changed to 'if(command == "that's all")' it never triggers. A little testing suggested that all of the whitespace was removed from the command.
Could someone explain to me what's going on here?
Thanks
The formatted input operator >>() reads space separated tokens from input. If you want to read whole lines, use the getline() function:
string command;
getline( cin, command );
Most (possibly all) operating systems buffer input. When you type a string of words and then hit [enter] it is only at the time you hit enter that the input is usually passed to your program. Thus that is when it will start reading the input and separating it out into individual words (because as Neil mentions, the >> reads words, not lines). Thus your program goes through the loop multiple times (once per word you had in the line) even though you only hit enter once.
So, you are correct when you think it should only display "could you..." once per loop. That is what is happening.
Likewise, you'll never have a command that contains more than one word because of the space delimiter. As mentioned, use getline() to retrieve the entire text for the line you entered.