I have input stream problem where my Console::ReadLine() command gets "eaten" when I try to loop my program back to start. Here is the code

#include "stdafx.h"

using namespace System;
int factorization();

int main(array<System::String ^> ^args)
{
	int terminate;

	do{
		terminate = factorization();
	}while(terminate == 'y' || terminate == 'Y');
	

	Console::ReadLine();
	return 0;
}

int factorization()
{
    Console::WriteLine(L"This application will factor any interger into its prime number form!");
	int intfac = 0;
	
	do{
	try
	{		
	    Console::Write(L"Please enter your integer:");
		intfac = Int32::Parse(Console::ReadLine());
	}
	catch (FormatException^)
	{
		Console::WriteLine(L"Your input is not an integer\n");
		intfac = 0;
	}
	}while(intfac == 0);

	array<int>^ data = gcnew array<int>(intfac);

	for( int i = 0; i<intfac; i++)
	{
		data[i] = 0;
	}

	int factor = intfac;

	for( int i = 0; i<factor ; i++)
	{
		while(factor%(i+2)==0)
		{
			factor /= (i+2);
			data[i]++;
		}
	}

	Console::Write(L"The unique factorization of {0} is:",intfac);
    Console::Write(factor);

	for( int i=0 ; i<intfac; i++)
		if (data[i] != 0)Console::Write(L"*({0})^{1}",i+2,data[i]);

	Console::Write(L"\n");
	Console::Write(L"Do you wish to continue?y/n:");
	return Console::Read();
}

the command: intfac = Int32::Parse(Console::ReadLine());
works fine when I initiate the program. However, it gets "eaten" when I loop the code back to start when I input 'y' in the end of factorization() function with this code line
return Console::Read();

It loops backs to begining and skip intfac = Int32::Parse(Console::ReadLine());, which cause the FormateException. This time, after the exception loop me back to the begining, the input command worked once again.

I want to know if there is anyway to fix this type of problem in C++/CIL programming

Dani AI

Generated

Good diagnosis from — the leftover Enter keystroke in the console input is the root cause. Building on that, a more robust pattern is to (a) validate numeric input with TryParse instead of letting Parse throw exceptions and (b) read a single confirmation key with ReadKey (or read the whole line and inspect the first character). The two short patterns below avoid the “eaten” ReadLine symptom and make the control flow clearer.

int n;
while (true) {
    Console::Write("Please enter an integer: ");
    String^ line = Console::ReadLine();
    if (Int32::TryParse(line, n) && n != 0) break;
    Console::WriteLine("Invalid integer; try again.");
}
Console::Write("Do you wish to continue? (y/n): ");
ConsoleKeyInfo k = Console::ReadKey(true);
bool continueLoop = (k.Key == ConsoleKey::Y);

Additional notes: return a bool from the factorization routine rather than an int code, then loop in main while(factorization()) for clarity. Validate the numeric bounds before allocating an array sized by the input (very large or negative values will crash or exhaust memory). Prefer TryParse to avoid exception-heavy control flow and echo the raw input when parsing fails for easier debugging. If ReadKey is not suitable, reading a whole line and checking its first non-whitespace character also works and keeps the input buffer clean.

Recommended Answers

All 3 Replies

Console::Read() only reads a single key from the keyboard buffer. When you type 'Y' followed by a <Enter> key there are two keys, not one, in the keyboard buffer. You have to remove the '\n' so that Console::Readline() can work properly.

One way to fix that is to use Console::Readline(), not Read() to get the 'Y' or 'N' response. Another way is to flush the keyboard buffer of all keys by calling Console::Read() in a loop until it returns '\n',

What is the point of Console::Read() when we have Console::ReadLine()?
It seems that I have to do more work when using Console::Read() as input command.

and by Console::Read() returning '\n', does it mean that I have to overload the Console::Read() function so that when I type 'Y' then press <enter> it only reads 1 key or something?

Thanks for the solution for my problem. I guess I'll avoid using Console:Read()

Console::Read() only reads a single key from the keyboard buffer. When you type 'Y' followed by a <Enter> key there are two keys, not one, in the keyboard buffer. You have to remove the '\n' so that Console::Readline() can work properly.

One way to fix that is to use Console::Readline(), not Read() to get the 'Y' or 'N' response. Another way is to flush the keyboard buffer of all keys by calling Console::Read() in a loop until it returns '\n',

Thank you very much

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.