Printing a value for the space character? - c++

I am making a program to translate English to Morse Code, using a series of conditional statements. I am using the following function:
void english (char text1){
if (text1=='a'||text1=='A'){cout<<".- ";}
else if (text1=='b'||text1=='B'){cout<<"-... ";}
.
.
.
else if (text1=='z'||text1=='Z'){cout<<"--.. ";}
else if (text1==' '){cout<<"/";}
}
There's one very simple problem. I cannot get my program to print anything for when there is a space character in the input; it should print a slash. I also tried else if (isspace(text1)) instead of else if (text1==' '), but with no luck.

The problem is not in the function you have posted code for. The problem is in the code which reads input. You may for example need to use std::getline(cin, line) to get an entire line with whitespace intact, or perhaps easier, get one character at a time:
for (char ch; cin.get(ch); ) {
english(ch);
}

Related

Formatting Output c++

Wanting to do some fancy formatting. I have several lines that I want to interact with each other. Get the first two lines. Print out the character in the second line times the integer in the first line. Seperate them all with a asterisk character. No asterisk after the final character is printed. Move onto the next integer and character. Print them on a separate line. Do this for the whole list. The problem I am having is printing them on separate lines. Example:
5
!
2
?
3
#
Desired output:
!*!*!*!*!
?*?
#*#*#
My output:
!*!*!*!*!*?*?*#*#*#*
Below is my code. Another thing to mention is that I am reading the data about the characters and numbers from a separate text file. So I am using the getline function.
Here is a chunk of the code:
ifstream File
File.open("NumbersAndCharacters.txt")
string Number;
string Character;
while(!File.eof(){
getline(File, Number);
getline(File, Character);
//a few lines of stringstream action
for (int i=0; i<=Number; i++){
cout<<Character<<"*";}//end for. I think this is where
//the problem is.
}//end while
File.close();
return 0;
Where is the error? Is it the loop? Or do I not understand getline?
It should be printing an "endl" or "\n" after each multiplication of the character is done.
Thanks to everyone for the responses!
You have not shown your code yet, but what seems to be the issue here is that you simply forgot to add a new line every time you print your characters. For example, you probably have done:
std::cout << "!";
Well, in this context you forgot to add the new line ('\n'), so you have two options here: first insert the new line yourself:
std::cout << "! \n";
Or std::endl;
std::cout << "!" << std::endl;
For comparison of the two, see here and here. Without further description, or more importantly your code that doesn't seem to work properly, we can't make suggestions or solve your problem.

Simple C++ not reading EOF

I'm having a hard time understanding why while (cin.get(Ch)) doesn't see the EOF. I read in a text file with 3 words, and when I debug my WordCount is at 3 (just what I hoped for). Then it goes back to the while loop and gets stuck. Ch then has no value. I thought that after the newline it would read the EOF and break out. I am not allowed to use <fstream>, I have to use redirection in DOS. Thank you so much.
#include <iostream>
using namespace std;
int main()
{
char Ch = ' ';
int WordCount = 0;
int LetterCount = 0;
cout << "(Reading file...)" << endl;
while (cin.get(Ch))
{
if ((Ch == '\n') || (Ch == ' '))
{
++WordCount;
LetterCount = 0;
}
else
++LetterCount;
}
cout << "Number of words => " << WordCount << endl;
return 0;
}
while (cin >> Ch)
{ // we get in here if, and only if, the >> was successful
if ((Ch == '\n') || (Ch == ' '))
{
++WordCount;
LetterCount = 0;
}
else
++LetterCount;
}
That's the safe, and common, way to rewrite your code safely and with minimal changes.
(Your code is unusual, trying to scan all characters and count whitespace and newlines. I'll give a more general answer to a slightly different question - how to read in all the words.)
The safest way to check if a stream is finished if if(stream). Beware of if(stream.good()) - it doesn't always work as expected and will sometimes quit too early. The last >> into a char will not take us to EOF, but the last >> into an int or string will take us to EOF. This inconsistency can be confusing. Therefore, it is not correct to use good(), or any other test that tests EOF.
string word;
while(cin >> word) {
++word_count;
}
There is an important difference between if(cin) and if(cin.good()). The former is the operator bool conversion. Usually, in this context, you want to test:
"did the last extraction operation succeed or fail?"
This is not the same as:
"are we now at EOF?"
After the last word has been read by cin >> word, the string is at EOF. But the word is still valid and contains the last word.
TLDR: The eof bit is not important. The bad bit is. This tells us that the last extraction was a failure.
The Counting
The program counts newline and space characters as words. In your file contents "this if fun!" I see two spaces and no newline. This is consistent with the observed output indicating two words.
Have you tried looking at your file with a hex editor or something similar to be sure of the exact contents?
You could also change your program to count one more word if the last character read in the loop was a letter. This way you don't have to have newline terminated input files.
Loop Termination
I have no explanation for your loop termination issues. The while-condition looks fine to me. istream::get(char&) returns a stream reference. In a while-condition, depending on the C++ level your compiler implements, operator bool or operator void* will be applied to the reference to indicate if further reading is possible.
Idiom
The standard idiom for reading from a stream is
char c = 0;
while( cin >> c )
process(c);
I do not deviate from it without serious reason.
you input file is
this is fun!{EOF}
two spaces make WordCount increase to 2
and then EOF, exit loop! if you add a new line, you input file is
this is fun!\n{EOF}
I took your program loaded it in to visual studio 2013, changed cin to an fstream object that opened a file called stuff.txt which contains the exact characters "This is fun!/n/r" and the program worked. As previous answers have indicated, be careful because if there's not a /n at the end of the text the program will miss the last word. However, I wasn't able to replicate the application hanging in an infinite loop. The code as written looks correct to me.
cin.get(char) returns a reference to an istream object which then has it's operator bool() called which returns false when any of the error bits are set. There are some better ways to write this code to deal with other error conditions... but this code works for me.
In your case, the correct way to bail out of the loop is:
while (cin.good()) {
char Ch = cin.get();
if (cin.good()) {
// do something with Ch
}
}
That said, there are probably better ways to do what you're trying to do.

My code is written twice for uncomprehensible reasons

This code is written in C++ and for reasons that I don't quite understand it is written twice.
I would expect that after inputting a random char it would display the char once and the String lower to it once as well. But I don't get this as output. What am I missing?
Solution: Adding a cin.ignore() statement disregards the return that is read in as well.
Making my code go through the loop once.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
char letter;
letter = cin.get();
while (letter!= 'X')
{
cout << letter << endl;
cout << "this will be written twice for ununderstandable reasons";
letter = cin.get();
}
}
Example:
If I were to write in cmd scrn c, I'd get a c back + twice the phrase this will be written twice for ununderstandable reasons. So what I thought to be the output
c
this will be written twice for ununderstandable reasons
is actually
c
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
as everyone already mentioned, cin will append the newline marker \n every time you hit enter. another solution is to place cin.ignore(); after every cin.get();.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
char letter;
letter = cin.get();
cin.ignore();
while (letter!= 'X')
{
cout<<letter<<endl;
cout<<"this will be written twice for ununderstandable reasons";
letter= cin.get();
cin.ignore();
}
}
You are reading every character with the unformatted get() function, including the newline character each time you hit return.
Depending on what you're trying to do, you could use formatted input (cin >> c) to skip all whitespace; or you could test each character and ignore things like newline that don't interest you; or you could use getline(cin, some_string) to read a whole line, and then process that.
When you type in a character the new-line character (from pressing enter) is also in your input buffer.
From the C-Reference:
The delimiting character is not extracted from the input sequence if found, and remains there as the next character to be extracted from the stream (see getline for an alternative that does discard the delimiting character).
Just use a cin.sync() after every cin.get() to clear the buffer and you should be good to go.
You forgot about the newline.
cin reads every character, which includes the newline you type after typing your character.
If you don't want this behaviour, you have to specifically check for newline.
while (letter!= 'X')
{
if (letter == '\n')
{
letter = cin.get();
continue;
}
cout<<letter<<endl;
cout<<"this will be written twice for ununderstandable reasons";
letter= cin.get();
}
The text 'this will be written twice..' will not necessarily print twice.
Type 'qwerty' + ENTER and your stream will have "qwerty\n" within and you'll see this output:
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
this will be written twice for ununderstandable reasons
Exactly that many as string "qwerty\n" has characters.
The problem is that
cin.get()
Puts all chars that you type into a stream/buffer (not your letter char) but handles one char every cin.get() invocation.
When you type 'abcXd' + enter - the program will print above line 3 times and stop on X.
It happens because cin.get() reads new-line character too. Try to press Enter without any symbols or type some string, like abc.
You need to handle it, e.g.:
while (letter = cin.get()) {
if (!isalpha(letter)) { continue; }
// handling user inputted alpha
}

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

Using cin.get() to grab a line of text, then using it in a loop to display that line?

Ok, so I came across this code snippet in my textbook that's supposed to echo every other character a user types in. Now, I understand the every other character part, but I'm having difficulty with the use of cin.get(). I understand why the first cin.get() is there, but why is it also inside the loop? I'm guessing I'm not fully grasping the nature of input streams...
EDIT: It just clicked... I'm an idiot. Thanks for clearing that up.
char next;
int count = 0;
cout << "Enter a line of input:\n";
cin.get(next);
while (next != '\n')
{
if ((count%2) == 0)
cout << next;
count++;
cin.get(next);
}
Thanks in advance!
cin.get in this case does not "grab a line of text" as you seem to believe. cin.get in this case grabs just a single character. With cin.get you read characters the user is typing in, one by one, one after another. This is why you have cin.get in a loop.
The call to cin.get(next) that comes before the loop is only placing the first character of buffered user input into the variable 'next.'
Once inside the loop, and the character stored in 'next' has been processed (echoed if at an even index, otherwise ignored), cin.get(next) needs to be called again to retrieve the next character.
Its printing characters present at even positions
char next;
int count = 0;
cout << "Enter a line of input:\n";
cin.get(next);//gets first character (position zero) from input stream
while (next != '\n')//check whether the character is not line feed(End of the line)
{
if ((count%2) == 0)//checks if position is even
cout << next; //if yes print that letter
count++; //increments the count
cin.get(next); //gets next character from input stream
}
We require two cin.get(...)
before entering the while loop we need to know first character(position zero)
inside while loop for getting next character
but what is the use of outside cin.get(ch) what does it do
how cin.get() works inside loop
both behaviours are lookin different
so it's making confusing
there is a statement in loop to print the character got using cin.get(next) but it will not print it.... it will print all together after pressing enter key ... actually it should display the characters as we type from the keyboard but it is not actually working like that
istream& get(char &c) gets a character from the input stream.
so on the first call cin.get(next) you typed:
"hello world!"
Then future cin.get(next) will fetch h, e, l, l, etc... on every call until the there are no more characters in the input stream and that's when it will block asking the user for more input.
Streams in C++ , are buffered. Think of them as a line of letters. When you call cin.get(var) the first character in that line is removed and returned to you. So, that's how it works.
An example would help better. When the first cin.get() is executed, let's say you type in :
LISP
and then, cin.get() will return (in the var.) L and then the buffer will look like ISP... the next call will place I in the var. and the buffer will look like SP and so on...