do while loop repeating cout line twice every loop? [duplicate] - c++

This question already has answers here:
My code is written twice for uncomprehensible reasons
(6 answers)
Closed 6 years ago.
Every time I run my program, the output in the first line of the do while loop repeats itself. So the output "Enter characters to add..." is output twice at the start of each loop. How do I make it only output once every loop repetition?
main file
#include "LinkedList.h"
#include "ListNode.h"
#include "Node.h"
#include <iostream>
#include <stdlib.h>
using namespace std;
LinkedList<char> *setUpSentence() {
//allocate the linked list objet
LinkedList<char> *sentence = new LinkedList<char>();
char ch;
do {
cout << "Enter characters to add, enter full stop to finish adding." << endl;
ch = cin.get();
sentence->addAtEnd(ch);
} while (ch != '.');
return sentence;
}
int main() {
//call the function, store the returned pointer in sentence variable
LinkedList<char> *sentence = setUpSentence();
while(sentence->size > 0) {
cout << sentence->removeAtFront() << endl;
}
//delete to avoid memory leak
delete sentence;
}

The problem is in here ch = cin.get();. It will automatically read whatever left in the input stream. You need to clean it first with this.

Your program is reading from standard input buffer. Read more about this in
"What is the standard input buffer?"
If you wish to repeat "cout" only once, rewrite it as follows:
char ch;
cout <<"char"<<ch<< "Enter characters to add, enter full stop to finish adding." << endl;
do {
ch = cin.get();
} while (ch != '.');

Related

While loop will only terminate if I use CTRL + C on the terminal

The prompt of the question is:
Write a program that prompts the user to input the name of a text file and then outputs the number of words in the file. You can consider a “word” to be any text that is surrounded by whitespace (for example, a space, carriage return, newline) or borders the beginning or end of the file.
I have successfully gotten the program to count how many words are in a file; no issues there.
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <string>
int main()
{
char file_name[16];
std::ifstream in_stream;
int count = 0;
char ch;
bool lastWasWhite = true;
std::string next;
// Ask the user for the file name
std::cout << "What is the name of the file? ";
std::cin >> file_name;
in_stream.open(file_name);
// See if we can open the file
if (!in_stream.is_open()) {
std::cout << "Something went wrong when opening your file.";
exit(1);
}
// Read the file, one character at a time
while (in_stream >> next) {
do {
std::cin.get(ch);
}
while (ch != ' ' && ch != '\n' && ch != '\t');
++count;
}
in_stream.close();
std::cout << "The file " << file_name << " contains " << count << " words." << std::endl;
return 0;
}
The only problem is that the only way for the program, or I think the "while loop" to finish, is for me to hit CTRL + C on the terminal so it force stops. Then I get the result I want.
This is my first post, so please let me know if there is any other information you would like to see.
Your outer loop is reading words from the file and counting them just fine (operator>> handles the whitespace for you).
However, your outer loop is also running an inner loop that is reading user input from stdin (ie, the terminal). That is where your real problem is. You are waiting on user input where you should not be doing so. So, simply get rid of the inner loop altogether:
while (in_stream >> next) {
++count;
}
That is all you need.

One extra line being read in file handling

I am trying to get the number of lines and words from a text file in c++. But one extra line is being read by compiler.
#include <iostream>
#include<fstream>
using namespace std;
int main(void)
{
ifstream f;
string name;
char a;
int line, words;
line = 0;
words = 0;
f.open("file.txt");
while (f) {
f.get(a);
if (a == '\n')
{
line++;
words++;
}
if (a == ' ')
{
words++;
}
}
f.close();
cout << "Number of words in file : " << words << endl;
cout << "Numbers of lines in the file : " << line << endl;
}
OUTPUT:-
Number of words in file : 79
Numbers of lines in the file : 3
file.txt:-
This C++ Program which counts the number of lines in a file. The program creates an input file stream, reads a line on every iteration of a while loop, increments the count variable and the count variable is printed on the screen.
Here is source code of the C++ program which counts the number of lines in a file. The C++ program is successfully compiled and run on a Linux system. The program output is also shown below.
I am puzzled why one extra line is being read. Kindly help.
You are not checking if f.get() succeeds or fails. When it does fail, a is not updated, and you are not breaking the loop yet, so you end up acting on a's previous value again. And then the next loop iteration detects the failure and breaks the loop.
Change this:
while (f) {
f.get(a);
...
}
to this instead:
while (f.get(a)) {
...
}
That being said, you are also not taking into account that the last line in a file may not end with '\n', and if it does not then you are not counting that line. And also, you are assuming that every line always has at least 1 word in it, as you are incrementing words on every '\n' even for lines that have no words in them.
I would suggest using std::getline() to read and count lines, and std::istringstream to read and count the words in each line, eg:
#include <fstream>
#include <sstream>
#include <string>
#include <cctype>
using namespace std;
int main(void)
{
ifstream f;
string line, word;
int lines = 0, words = 0;
f.open("file.txt");
while (getline(f, line))
{
++lines;
std::istringstream iss(line);
while (iss >> word) {
++words;
}
}
f.close();
cout << "Number of words in file : " << words << endl;
cout << "Numbers of lines in the file : " << line << endl;
}
It is because you do not check in what state is stream that f.get(a) returns.

How do I get a C++ program to count the number of words as a user enters input?

I'm trying to write a program that keeps taking input from the user until the user enters "quit." Each time the user enters input, I want the program to print out the number of words the user has entered. So the following input on the user's part:
hello how are you
would yield the following output:
You entered 4 words.
However, I am having trouble writing the program so that it counts the number of words on just one line; it doesn't clear the number before going onto the next line. So, if it took input from the user three times, it would add up the total number of words on those three lines. For example, the following input:
how are you
i am good thank you
quit
would yield the following output:
You entered 9 words.
when I want it to output the number of words following each line the user enters (except quit), i.e.
>>how are you
<<You entered 3 words.
>>i am good thank you
<<You entered 5 words.
>>quit
Here's the relevant bit of my code:
char *input;
int inum;
int inputLoop()
{
char quit[] = "quit";
inum = 0; //counts number of words
while (strcmp(input, quit) != 0)
{
cin >> input;
inum++;
}
cout <<"You entered " <<inum <<" words." <<endl;
I'd rather not use something like a vector; whatever I use will need to be converted to a *char eventually because my global variable is a *char. (And my global variable is a *char because, depending on certain conditions, *input may be set to *argv[] from main.)
I've tried all sorts of things, but I just can't seem to get past the fact that strcmp(input, quit) compares one word of the input at a time to quit rather than comparing the entire input line to quit. HELP.
None of your requirements precludes the use of std::string and std::vector. I recommend you use them.
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
std::vector<std::string> words;
int inputLoop()
{
char quit[] = "quit";
total_words = 0;
std::string line;
// grab a line at a time
while(std::getline(std::cin, line) && line != quit) {
// clear the vector of words
words.clear();
// make a string stream to read words from that line
std::stringstream ss(line);
// grab all the words into a vector
std::string word;
while(ss >> word) {
words.push_back(word);
}
std::cout <<"You entered " <<words.size() <<" words." <<endl;
}
}
int main(int argc, char** argv) {
// get the data from argv
words = std::vector<std::string>(argv, argv + argc);
}
You should use getline() to get an entire line of input into some buffer. Then, process that buffer of input to count the number of words in it. Assuming you define each word to be a block of characters separated by a space. Myself, I am a fan of strtok() for breaking up a buffer.
An alternative approach, just for fun:
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
unsigned num = 0;
std::for_each(
std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
[&num](const std::string& s)
{
if (s == "quit")
std::cin.setstate(std::ios::eofbit);
++num;
if (std::cin.peek() == '\n') {
std::cout << "You entered "
<< num
<< " word"
<< ((num == 1) ? "." : "s.")
<< '\n';
num = 0;
}
});
}
Doesn't waste resources by tokenizing a line into a vector :)
I would call distance
#include <string>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <sstream>
int main()
{
std::string line;
while(std::getline(std::cin, line) && line != "quit")
{
std::stringstream linestream(line);
std::cout << "You entered "
<< std::distance(std::istream_iterator<std::string>(linestream),
std::istream_iterator<std::string>())
<< " words\n";
}
}

HW Help: get char instead of get line C++

I wrote the code below that successfully gets a random line from a file; however, I need to be able to modify one of the lines, so I need to be able to get the line character by character.
How can I change my code to do this?
Use std::istream::get instead of std::getline. Just read your string character by character until you reach \n, EOF or other errors. I also recommend you read the full std::istream reference.
Good luck with your homework!
UPDATE:
OK, I don't think an example will hurt. Here is how I'd do it if I were you:
#include <string>
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
static std::string
answer (const string & question)
{
std::string answer;
const string filename = "answerfile.txt";
ifstream file (filename.c_str ());
if (!file)
{
cerr << "Can't open '" << filename << "' file.\n";
exit (1);
}
for (int i = 0, r = rand () % 5; i <= r; ++i)
{
answer.clear ();
char c;
while (file.get (c).good () && c != '\n')
{
if (c == 'i') c = 'I'; // Replace character? :)
answer.append (1, c);
}
}
return answer;
}
int
main ()
{
srand (time (NULL));
string question;
cout << "Please enter a question: " << flush;
cin >> question;
cout << answer (question) << endl;
}
... the only thing is that I have no idea why do you need to read string char by char in order to modify it. You can modify std::string object, which is even easier. Let's say you want to replace "I think" with "what if"? You might be better off reading more about
std::string and using find, erase, replace etc.
UPDATE 2:
What happens with your latest code is simply this - you open a file, then you get its content character by character until you reach newline (\n). So in either case you will end up reading the first line and then your do-while loop will terminate. If you look into my example, I did while loop that reads line until \n inside a for loop. So that is basically what you should do - repeat your do-while loop for as many times as many lines you want/can get from that file. For example, something like this will read you two lines:
for (int i = 1; i <= 2; ++i)
{
do
{
answerfile.get (answer);
cout << answer << " (from line " << i << ")\n";
}
while (answer != '\n');
}

C++ program not moving past cin step for string input

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