A large input from console in C++ - c++

I need to enter more than 10000 integers, smaller than max long long directly into console. The console accepts something more than 9000 of them using getline(cin,string). Inputting them one by one slows my program dramatically. Is there anyway that I can override the console's getline maximum input?
[Edited to include the OP's comment:]
#include <iostream>
using namespace std;
int main()
{
long long n=0,i=0,a,b;
cin>>n;
for(i=0;i<n;i++) { cin>>a>>b; cout<<a+b<<endl; }
return 0;
}
This code gives a "Time Limit Exceeded" error on the task when more than 10000 integers are inputted.
EDIT:
After rewriting the code with help from one answer:
#include <iostream>
static inline int error(int n) { std::cerr << "Input error!\n"; return n; }
int main()
{
long long a,b,n; // number of colours and vertices
if (!(std::cin>> n)) { return error(1); }
for (int i = 0; i != n; ++i)
{
if (!(std::cin >> a>>b)) { return error(1); }
std::cout << a+b << "\n";
}
}
Now it gives me a Runtime Error(NZEC) on the test case with 10000+ integers
EDIT 2:
I found something that would help me but it is only in C# : How to read very long input from console in C#?
Couldn't find an equivalent in C++

By default iostreams are synchronized with C stdio functions and that makes them too slow for algorithmic contests. Disable synchronization at the beginning of your program:
std::ios::sync_with_stdio(false);

You can take input from file. All you have to do is to redirect the stdin like this
if (!freopen("filename.txt", "r", stdin)) {
cout << "Could not open file";
return 1;
}
long long n=0,i=0,a,b;
cin>>n;
for(i=0;i<n;i++) { cin>>a>>b; cout<<a+b<<endl; }
return 0;

Related

Abort signal from abort(3) (SIGABRT) in C++

#include <iostream>
using namespace std;
int main()
{
//code
int test;
cin >> test;
while(test--)
{
int count = 0;
string input;
cin >> input;
for (int j = 0; j < input.length() - 2; j++)
{
if (input.substr(j, 3) == "gfg")
{
count +=1;
}
}
if (count > 0)
{
cout << count << endl;
}
else
{
cout << -1 << endl;
}
}
return 0;
}
This code shows Abort signal from abort(3) (SIGABRT) while submitting in Geeks for Geeks while runs perfectly on the local computer and even works perfectly on various online compilers. Can't figure out the problem. Can someone help?
Think about what happens when input has fewer than two characters.
input.length() is an unsigned quantity, so input.length() - 2 then would wrap around to an astronomically large number.
input.substr(j, 3) isn't good when j is an astronomically large number: it throws the exception std::out_of_range; since you're not catching this exception, your program terminates.
These contests test to see whether you cover all your possible input domains, especially edge cases. Be sure to consider them when you write your algorithm.

Is there a way to have exceptions work indefinitely?

I have been trying to take an input from the user. I want to ensure that the input meets my requirements for the rest of the code for which I have used a try and catch block.
However, after only one time catching, it aborts the code. I want to ensure that after catching error it actually goes back to the input function for as many times until the user gives the program a valid input. Is there a way to do that except not using try catch blocks altogether?
Here's the code:
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
long num; // I need num as global
long get_input()
{
string input;
long number;
cout << "Enter a positive natural number: ";
cin >> input;
if ( !(stol(input)) ) // function for string to long conversion
throw 'R';
number = stol(input);
if (number <= 0)
throw 'I';
return number;
}
int main()
{
try
{
num = get_input();
}
catch (char)
{
cout << "Enter a POSTIVE NATURAL NUMBER!\n";
}
// I want that after catch block is executed, the user gets chances to input the correct number
// until they give the right input.
return 0;
}
You need explicitly write such a handling, e.g. via loop:
int main()
{
while (1) {
try
{
num = get_input();
return 0; // this one finishes the program
}
catch (char)
{
cout << "Enter a POSTIVE NATURAL NUMBER!\n";
}
}
}

why does my calculator program start flashing and scrolling when i enter a large number

my program is a calculator that currently only does addition and subtraction, but when i input a large number it starts flashing and scrolling. it works fine for small numbers. the program isn't long so here it is. a youtube video of the problem https://youtu.be/Fa03WtgXoek
#include <iostream>
int GVFU()
{
std::cout <<"enter number";
int a;
std::cin >> a;
return a;
}
int add()
{
int x = GVFU();
int y = GVFU();
int z = x + y;
std::cout <<z <<std::endl;
return 0;
}
int subtract()
{
int x = GVFU();
int y = GVFU();
int z = x - y;
std::cout <<z << std::endl;
return 0;
}
int main()
{
for ( ; ; )
{
std::cout << "enter 1 for addition and 2 for subtraction";
int c;
std::cin >> c;
if (c==1)
{
add();
}
if (c==2)
{
subtract();
}
std::cout << "press 1 to end";
int e;
std::cin >>e;
if (e==1)
{
return 0;
}
}
}
If you try to read a value from cin and the value read doesn't match the expected format, it causes the stream to fail and all future read operations will instantly return without reading anything.
Independently, in C++ integer values for the int type have a minimum and maximum possible value that depends on what compiler and system you're using. If you exceed that value when entering a number, cin will consider it a failed read.
Putting this together, once you enter a value that's too large, the program will keep running through the main loop in your program, prompting for a value, instantly returning without actually getting user input, then calculating garbage values.
To fix this, you'll need to either (1) just hope the user doesn't type in anything unexpected or (2) get user input more robustly. There are a number of good explanations about how to do option (2) here on Stack Overflow, and now that you know what the root cause of the issue is you can hopefully get the code fixed and working!
Use
std::cout << std::numeric_limits<int>::max() << std::endl;
and include #include <limits> and you will find out max int value on your machine.
int on your system is likely a 32-bit signed two's complement number, which means the max value it can represent is 2,147,483,647.
If you add bigger number stream will fail and all next read operations will return without reading anything.
Use unsigned long long which will allow you to insert bigger numbers.
You are taking your inputs as " int " and value range for int is between -2,147,483,648 to 2,147,483,647.
Which means that if you exceed this value 2,147,483,647 it can not be stored as an integer(int) type.
You should probably use Long data type for such large numbers.
You can add a following check in your code if the user input more than int limit
int GVFU()
{
std::cout <<"enter number";
int a;
std::cin >> a;
if(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input " << endl;
}
return a;
}
I would also add exit if invalid number
#include <iostream>
#include <cstdlib>
using namespace std;
int GVFU()
{
std::cout <<"enter number";
int a;
std::cin >> a;
if(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input " << endl;
std::exit(EXIT_FAILURE);
}
return a;
}
Note: You could also more info instead of just "Invalid input "
Output like size or limit info
enter 1 for addition and 2 for subtraction1
enter number4535245242
Invalid input
Program ended with exit code: 1

How to use file with integer into an array C++

My task is to create a program to ensure that unauthorized users cannot get into the system. (This is just a scenario, not the real thing). I was given a text file with 300 numbers on it. The user has to type in the number, if it is not included in the text file access will be denied. If it is included in the text file, access will be granted. The rest will be shown below.
So far this is what I have done
#include <iostream>
#include <fstream>
using namespace std;
bool mySequentialSearch(int data[300], int key, int size)
{
for(int i=0; i<size; i++)
{
if (data[i] == key)
return true;
}
return false;
}
int main()
{
int codes;
string line;
ifstream fin ("SystemAccessCodes.txt");
while (fin>>codes)
{
for(int i=0; i<3; i++)
{
cout<<"\nAttempt "<< i+1 << "/3 : ENTER 4 DIGIT CODE: ";
int ans;
cin>>ans;
if(mySequentialSearch(&codes, ans, 300))
{
cout<<"===================="<<endl;
cout<<" Access Granted "<<endl;
cout<<" Welcome "<<endl;
cout<<"===================="<<endl;
system ("pause");
return 0;
}
else
{
cout<<"\nNot matching! Try Again"<<endl;
}
fin.close();
}
}
system ("pause");
return 0;
}
My problem is I don't know how to use the textfile as an array. And it only reads the first number of the file.
Here is some of the numbers in the file (1450
1452
1454
1456
1458
1460) and the program I built only reads 1450.
Separate reading the codes and checking the user input. It makes no sense to do all that in a single loop.
int codes[300];
for(int i = 0; i < 300 && fin; ++i) {
fin>>codes[i];
}
fin.close();
for(int i=0; i<3; i++)
{
cout<<"\nAttempt "<< i+1 << "/3 : ENTER 4 DIGIT CODE: ";
int ans;
cin>>ans;
if(mySequentialSearch(codes, ans, 300))
{
cout<<"===================="<<endl;
cout<<" Access Granted "<<endl;
cout<<" Welcome "<<endl;
cout<<"===================="<<endl;
system ("pause");
return 0;
}
else
{
cout<<"\nNot matching! Try Again"<<endl;
}
}
The better way in c++ is to use a std::vector<int> instead of the raw array though:
std::vector<int> codes;
int code;
while(fin>>code) {
codes.push_back(code);
}
Instead of your mySequentialSearch() function, you can simply use std::vector::find() then.
Here you go:
I think it would be good to use an unordered_set here. To get that, make sure you use #include <unordered_set>
int codes;
std::string line;
std::ifstream fin("SystemAccessCodes.txt");
//lets use a set.
//Sets cannot contain duplicates. If the number is in the set, it is a valid code.
//it might be a better option to use strings rather than ints as passwords
//(large numbers could cause problems)
std::unordered_set<int> codeset;
//populate the set
while (fin >> codes)
{
codeset.insert(codes);
}
fin.close();
//now run this iteration
for (int i = 0; i < 3; i++)
{
std::cout << "\nAttempt " << i + 1 << "/3 : ENTER 4 DIGIT CODE: ";
int ans;
std::cin >> ans;
//count returns either 0 or 1: 0 if the ans is not in it, 1 if it is
if(codeset.count(ans))
{
std::cout << "====================\n";
std::cout << " Access Granted \n";
std::cout << " Welcome \n";
std::cout << "====================\n";
system("pause");
return 0;
}
else
{
std::cout << "\nNot matching! Try Again" << std::endl;
}
}
system("pause");
return 0;
Notes:
Using "using namespace std" pollutes the global namespace. I prefer to use "std::"
Your mySequentialSearch causes an n^2 runtime of your program. Using sets cuts it down to n (linear).
For more information on sets: http://en.cppreference.com/w/cpp/container/unordered_set
For more information on ifstream: http://en.cppreference.com/w/cpp/io/basic_ifstream
It would probably be a good idea to add some error checking (file doesn't exist, bad input, etc.)

Display an array of 'double' numbers with unknown size in c++

Update 1: I need help with this the second part of this. I am asking the user to input numbers and to stop by using a zero. But then I want to display that code back. This is how far I got because when I want to display it it gives me different numbers. I'm ignoring user errors assuming when they input the first time it will be correct. But I do want them to input negative numbers.
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
float data;
int count=0;
int*arr=new int[count];
//get amount of numbers inputted
cout<<"Please enter floating point data.\n";
cout<<"After the last number has been entered press 0 (zero) \n";
cin>>data;
for (; data != 0 ; ++count)
{
cin>>data;
}
cout<<count<<endl;
cout<<endl;
//display back data
cout<<"The numbers enterd are: "<<endl;
for(int i=0; i<count; i++)
{
cout<<arr[i]<<endl;
}
cout<<endl;
system ("pause");
return 0;
}
**Update 2:**This code is part of a bigger project I'm working on. My professor is never going to see the code he just cares that it is working. The design of my code is not a priority in this case. Also I have never used std::vector before so I needed another way to do it. But this is what I did and it worked fine. I also commented off delete []arr because my code wouldn't run properly if I didn't do that.
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
double data;
int count=0;
double *arr =new double[count];
//get data
cout<<"Please enter floating point data."<<endl;
cout<<"After the last number has been entered press 0 (zero)"<<endl;
do
{
cin>>arr[count];
data = arr[count];
count++;
}while(data != 0);
//display back data
cout<<"The numbers entered are: "<<endl;
for(int i=0; i<(count-1); i++)
{
cout<<arr[i]<<endl;
}
//delete []arr;
system ("pause");
return 0;
}
The given example code,
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
float data;
int count=0;
int*arr=new int[count];
//get amount of numbers inputted
cout<<"Please enter floating point data.\n";
cout<<"After the last number has been entered press 0 (zero) \n";
cin>>data;
for (; data != 0 ; ++count)
{
cin>>data;
}
cout<<count<<endl;
cout<<endl;
//display back data
cout<<"The numbers enterd are: "<<endl;
for(int i=0; i<count; i++)
{
cout<<arr[i]<<endl;
}
cout<<endl;
system ("pause");
return 0;
}
… has many issues:
Coding: using float for no reason.
The default floating point type in C and C++ is double. E.g. the literal 3.14 is of type double, and any float value is promoted to double when passed to variadic C function. Only use float where a requirement is imposed by the context, e.g. a C API, or storing a zillion values in limited memory.
Coding: using a raw array and a new-expression.
The task is trivial when using std::vector. It's not a good idea to reinvent the wheel again and again. An exercise that requires you to reinvent std::vector or its most basic features should be very clear about that aspect: this isn't, so presumably reinvention is not required or what it's about.
Design: signalling end-of-input via special value.
That value can't be inputted.
Coding: an input loop that doesn't store the numbers.
Each number is stored in the same variable as the previous number, erasing the previous number. Store the numbers in a std::vector. E.g. you can use the push_back method.
Coding: inconsistent convention for newline on output.
Either use endl, or "\n", as default. Don't mix them randomly. Consistency is very important because someone reading the code, who assumes a competent programmer, must treat every departure from the established defaults as being due to some reason. When there is no reason this wastes time and effort.
Tool usage: the system( "pause" ) is silly, counter-productive & non-portable.
In Visual Studio, which it appears you're using, just run the program via Ctrl+F5. Or place a breakpoint on the last right brace of main, and run the program in the debugger via F5.
Coding: the return 0; is superfluous.
main is the only function that has a default return value. It has that in both C and C++. The default, 0 for success, is there to be used.
Example code with the above points, plus some, fixed.
This code is for C++11 or later so it won't compile directly with Visual C++ 2010.
I leave it as an exercise for you to translate it to C++03, which is what your current compiler can handle. Do consider upgrading. It's a free tool.
#include <iostream>
#include <iomanip> // std::setw
#include <string> // std::(string, stod)
#include <vector> // std::vector
using namespace std;
using Half_float = float; // Most often a silly choice.
using Float = double; // Default in C++.
using Extended_float = long double; // Same as double in Visual C++.
auto read_line()
-> string
{ string line; getline( cin, line ); return line; }
auto main() -> int
{
cout << "Please enter floating point numbers like " << 3.15 << ", one per line.\n";
cout << "After the last number just press return again (i.e. a blank line).\n";
vector<Float> numbers;
for( ;; )
{
cout << "#" << numbers.size() + 1 << "? ";
string const line = read_line();
if( line.empty() )
{
break;
}
numbers.push_back( stod( line ) ); // Here you CAN do input validation.
}
cout << numbers.size() << " numbers entered.\n";
cout << "\n";
cout << "The numbers entered were: \n";
for( int i = 0; i < int( numbers.size() ); ++i )
{
cout << setw( 3 ) << i << ": " << numbers[i] << "\n";
}
}
If you have C++ 11 or above, use auto
replace
for(int i=0; i<count; i++)
{
cout<<arr[i]<<endl;
}
with
for(auto v: arr){
cout << v << endl;
}
Please remember, you'll need compiler supporting C++11 to use auto.
If C++ < 11, Use std::for_each
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
void print(float v){
cout << v << endl;
}
int main ()
{
float data;
int count=0;
std::vector<float> arr;
//get amount of numbers inputted
cout<<"Please enter floating point data.\n";
cout<<"After the last number has been entered press 0 (zero) \n";
while(cin>> data && data != 0)
{
arr.push_back(data);
++count;
}
cout<<count<<endl;
cout<<endl;
//display back data
cout<<"The numbers enterd are: "<<endl;
std:for_each(arr.begin(), arr.end(), print);
cout<<endl;
system ("pause");
return 0;
}
The code will access out-of-bounds of arr, which has zero elements, unless you enter 0 for the first prompt.
You didn't assign what you read to "elements or arr" (actually there will be no elements in arr) at all.
There will be no reason why you should use array of int to store float data.
You should use std::vector, which works as variable-size array.
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
int main ()
{
float data;
int count=0;
vector<float> arr;
//get amount of numbers inputted
cout<<"Please enter floating point data.\n";
cout<<"After the last number has been entered press 0 (zero) \n";
while(cin >> data && data != 0)
{
arr.push_back(data);
}
count = arr.size();
cout<<count<<endl;
cout<<endl;
//display back data
cout<<"The numbers enterd are: "<<endl;
for(int i=0; i<count; i++)
{
cout<<arr[i]<<endl;
}
cout<<endl;
return 0;
}