I'm doing a relatively simple assignment asking us to intake integers and fail gracefully if it hits something that isn't an integer, written in C++. I'm fairly experienced with the language, and I knew it had functionality for checking reading errors in ios::failbit. As a result I'm using cin.fail() to check for errors here, but its running one loop too late--that is, its running the rest of the code first, and not realizing an error happened until the next time it checks the buffer. The obvious solution is to just check twice, but that just causes infinite loops (even if I flush or clear cin.) Is there any way to check more immediately?
Here's my code:
int min = 101; //One higher than the max.
int pile = 0;
int count = 0;
int temp = 0;
int fail;
std::cout << "Input a series of integers between 0 and 100. When you wish to"
" exit, enter -1.\n";
while (true){
std::cin >> temp;
if (std::cin.fail()){
std::cout << "FAILURE: Bad input. It probably wasn't an integer.\n";
std::cout << "Reading will stop.\n";
break;
}
std::cout << "\nTemp is " << temp << "\n";
if (temp > 100 || temp == -1){
break;
}
if (temp < min){
min = temp;
}
pile += temp;
std::cout << "Pile is " << pile << "\n";
count++;
std::cout << "Count " << count << "\n";
}
std::cout << "Your average was: " << (double)pile/count << ".\n";
std::cout << "Your minimum was: " << min << ".\n";
return 0;
}
Related
I usually return an object of std::vector or std::map as an incoming reference paremeter(as funcVec2 and funcMap2 below). But it is a bit inconvenient when writing codes. So I think if I can use return value under c++11(as funcVec1 and funcMap1 below) because it will call move constructor but not copy constructor, so it maybe still spend only one construct time and no deconstruct as the form of incoming reference paremeter.
But I write the codes below to verify it and it turns out that funcVec1 and funcMap1 takes more times then funcVec2 and funcMap2. So I am confused now why funcVec1 and funcMap1 takes so long?
#include <iostream>
#include <vector>
#include <map>
#include <chrono>
using namespace std;
vector<int> funcVec1() {
vector<int >vec;
for (int i = 0; i < 10; ++i) {
vec.push_back(i);
}
return vec;
}
void funcVec2(vector<int>&vec) {
for (int i = 0; i < 10; ++i) {
vec.push_back(i);
}
return;
}
map<int, int> funcMap1() {
map<int, int>tmpMap;
for (int i = 0; i < 10; ++i) {
tmpMap[i] = i;
}
return tmpMap;
}
void funcMap2(map<int, int>&tmpMap) {
for (int i = 0; i < 10; ++i) {
tmpMap[i] = i;
}
}
int main()
{
using namespace std::chrono;
system_clock::time_point t1 = system_clock::now();
for (int i = 0; i < 100000; ++i) {
vector<int> vec1 = funcVec1();
}
auto t2 = std::chrono::system_clock::now();
cout << "return vec takes " << (t2 - t1).count() << " tick count" << endl;
cout << duration_cast<milliseconds>(t2 - t1).count() << " milliseconds" << endl;
cout << " --------------------------------" << endl;
vector<int> vec2;
for (int i = 0; i < 100000; ++i) {
funcVec2(vec2);
}
auto t3 = system_clock::now();
cout << "reference vec takes " << (t3 - t2).count() << " tick count" << endl;
cout << duration_cast<milliseconds>(t3 - t2).count() << " milliseconds" << endl;
cout << " --------------------------------" << endl;
for (int i = 0; i < 100000; ++i) {
map<int, int> tmpMap1 = funcMap1();
}
auto t4 = system_clock::now();
cout << "return map takes " << (t4 - t3).count() << " tick count" << endl;
cout << duration_cast<milliseconds>(t4 - t3).count() << " milliseconds" << endl;
cout << " --------------------------------" << endl;
map<int, int>tmpMap2;
for (int i = 0; i < 100000; ++i) {
funcMap2(tmpMap2);
}
auto t5 = system_clock::now();
cout << "reference map takes " << (t5 - t4).count() << " tick count" << endl;
cout << duration_cast<milliseconds>(t5 - t4).count() << " milliseconds" << endl;
cout << " --------------------------------" << endl;
return 0;
}
you are not only meassuring the time for your operations, you also include the printouts. this is suboptimal.
you should measure performance in release mode. be aware that you are not doing anything usefull with your objects and the optimizer may throw away most of your code you wanted to measure.
the comparisons are not "fair". for example in your map1 case you are constructing an empty map, fill it (memory allocations happen here) and then you throw it away. in the map2 case you are reusing the identical map object over and over again. you are not allocating memory over and over again.
I've wrote some code to output certain students' grades if they're in between a lower bound and upper bound. I don't get any errors when I'm compiling the program but it's not writing to my csv file.
I suspect that there is a problem with my if-statement, where I wrote if(argv[3] && argv[4]) because it's just not executing this part of the code. Argv3 and 4 would be "D A" in the code. So I'd write:
g++ -std=c++11 studentData.cpp
and then:
./a.out output.csv D A
ofstream out_file;
out_file.open(argv[2]);
if(argv[3] && argv[4]){
string lower = argv[3];
string upper = argv[4];
int x = calcNum(lower);
int y = calcNum(upper);
cout << "lower is: " << lower << endl;
cout << "upper is: " << upper << endl;
for(int i= 0; i < length; i++){
if(students[i].average > x && students[i].average < y){
out_file << students[i].studentName << " earned " << students[i].average << " which is an " << calcLetter(students[i].average) << endl;
}
}
}
else {
cout << "Argv3 and Argv4 have not been detected";
}
out_file.close();
}
I was trying to run it, no matter what i insert into the queue and what the quantity of numbers inserted, it just does not display the circular queue.
These are some points over which i want a clarification and/or correction, would appreciate a response.
in the below code, in the function Insert_in_Cqueue(), towards the end, there is a statement 'rear++; Cqueue[rear] = ele;' , Does rear++ signify that we are moving forward towards the front from the rear, as that is how we insert in a circular queue?
in the function Del_from_Cqueue(), towards the end, there is a statement 'front++', all that it implies is that by incrementing 'front', we just lose track of the element concerned in that particular run of the function del_from_cqueue(), essentially implying that we have deleted the element which we wished to?
The code :
#include<iostream>
#include<conio.h>
#include<process.h>
using namespace std;
int Insert_in_CQueue(int[], int);
void Display(int[], int, int);
int Del_from_CQueue(int CQueue[]);
void main()
{
const int size = 7;
int CQueue[size];
int Item, res, ch, front = -1, rear = -1;
do
{
cout << "\t\t\t Circular Queue Menu\n";
cout << "\t 1. Insert\n";
cout << "\t 2. Delete\n";
cout << "\t 3. Display\n";
cout << "\t 4. Exit\n";
cout << "\n Enter your choice(1-4)";
cin >> ch;
switch (ch)
{
case 1: cout << "\t\t You have selected the option to 'Insert' in the Queue. ";
cout << "\n Enter item for insertion ";
cin >> Item;
res = Insert_in_CQueue(CQueue, Item);
if (res == -1)
{
cout << "\n Overflow encountered";
}
else
{
cout << "\n Now the circular Queue is : ";
Display(CQueue, front, rear);
}
break;
case 2: Item = Del_from_CQueue(CQueue);
cout << "\n Element deleted is : " << Item << endl;
Display(CQueue, front, rear);
break;
case 3: Display(CQueue, front, rear);
break;
case 4: break;
default: cout << "\n Valid choices are 1,2,3,4 only ";
break;
}
} while (ch != 4);
_getch();
return;
}
int Insert_in_CQueue(int CQueue[], int ele)
{
int front = -1, rear = -1;
const int size = 7;
if ((front == 0 && rear == (size - 1)) || (front == rear + 1)) //the
second condition, as it is a circular queue, no end
{
return -1;
}
else if (rear == -1)
{
front = rear = 0;
}
else if (rear == size - 1)
{
rear = 0;
}
else
rear++;
CQueue[rear] = ele;
return 0;
}
void Display(int CQueue[], int front, int rear)
{
int i = 0;
const int size = 50;
cout << "\n Circular Queue is : \n" << "(Front shown as >>>, Rear as <<<
AND Free space as->\n";
if (front == -1)
return;
if (rear >= front)
{
for (i = 0; i < front; i++) cout << "-";
cout << ">>>";
for (i = 0; i < rear; i++) cout << CQueue[i] << "<---";
cout << CQueue[rear] << "<<<" << endl;
}
else
{
for (i = 0; i < rear; i++) cout << CQueue[i] << "<---";
cout << CQueue[rear] << "<<<";
for (i = 0; i < front; i++) cout << "-";
cout << ">>>";
for (i = front; i < size; i++) cout << CQueue[i] << "<---";
}
}
int Del_from_CQueue(int CQueue[])
{
int ret;
int front = -1, rear = -1;
const int size = 50;
if (front == -1) return -1;
else
{
ret = CQueue[front];
if (front == rear) front = rear = -1;
else if (front == size - 1)
front=0;
else front++;
}
return ret;
}
The standard way of checking if a circular queue is full is
if((rear+1)%size == front)
Queue is Full.
The standard way of checking if a circular queue is empty is
if(rear==front)
Queue is Empty.
Remember: In a circular queue, the queue is considered full when one space is still empty. This is done to differentiate between condition of empty and full.
You do no simply increment the front and the rear while inserting or deleting the values. The values of front and rear need to be zero when they reach the queue size.
Eg: With a queue size of 7, when front or rear reaches the value of 6, theit next value should be zero and not 7
So while inserting, you should use:
rear=(rear+1)%size;
CQueue[rear] = ele;
And while deleting, you should use:
ret = CQueue[front];
front=(front+1)%size;
Your answer:
Yes ! When circular queue is empty, both the front and the rear are together. As we insert elements in the queue, the rear increases and the front remains constant. Increasing the rear value while inserting does not mean that we are moving towards the front from the rear, but when the queue approaches to be full, the front and the rear come together.
For example: If you run in a circular path from a starting point, you first move away from the starting point, but as you tend to complete the run, you approach the starting line from the back. Same goes with the circular queue.
I'm currently taking a C/C++ programming class at my school. I am tasked with writing a piece of code that will ask the user how many numbers they would like averaged, then averages them. The program has to contain a for loop. The problem that I am having is that after the user has entered the "n" variable, if they type a character such as "a", the program will immediately spit out an answer as my average. I would like to find a way to prevent the user from entering characters so that my for loop can finish running and average the numbers properly. Here is my code:
{
int n, i = 1, x = 1;
double sum = 0, average, value;
cout << "\nHow many numbers do you want to average?: ";
cin >> n;
while (n < 1)
{
cout << "\nYou have entered an invalid number.\n";
cout << "\nHow many numbers do you want to average?: ";
cin.clear();
while (cin.get() != '\n');
cin >> n;
}
for (n; i <= n; i++)
{
cout << "\nEnter value: ";
cin >> value;
sum = sum + value;
}
average = sum / n;
cout << "\nThe average is: " << average << endl;
system("pause");
return 0;
}
I am using VTK for a project an just can not seem to figure out a section of it. I am trying to iterate through several thousand points and find the 5 closest points every point. Seems like a simple for loop operation but my problem is that for some reason, I am being told that the same 5 points are the closest point for every point in my data...which I know is not true. I will attach the bit of code I am describing Below:
//test
vtkSmartPointer<vtkPointSource> pointSource =
vtkSmartPointer<vtkPointSource>::New();
pointSource->SetNumberOfPoints( Output->GetNumberOfPoints() );
pointSource->Update();
vtkSmartPointer<vtkKdTreePointLocator> Tree =
vtkSmartPointer<vtkKdTreePointLocator>::New();
Tree->SetDataSet( pointSource->GetOutput() );
Tree->BuildLocator();
unsigned int k = 5;
double testpoint[3];
vtkSmartPointer<vtkIdList> result =
vtkSmartPointer<vtkIdList>::New();
for(vtkIdType n = 0; n < Output->GetNumberOfPoints(); n++)
{
result->Reset();
Output->GetPoint( n,testpoint );
Tree->Update();
std::cout << "Point: " << testpoint[0] << ", " << testpoint[1] << ", " << testpoint[2] << ": " << endl;
Tree->FindClosestNPoints(k, testpoint, result);
for(vtkIdType i = 0; i < k; i++)
{
vtkIdType point_ind = result->GetId(i);
double p[3];
pointSource->GetOutput()->GetPoint(point_ind, p);
std::cout << "Closest point " << i+1 << ": Point "
<< point_ind << ": (" << p[0] << ", " << p[1] << ", " << p[2] << ")" << std::endl;
}
}
//end test
This is doing what I am trying to do...It is printing out the 5 closest points to the a point of interested, but despite the point of interest changing, the 5 closest points are remaining the same. I am assuming I am just passing over a small detail in my code but I could be wrong. If you need anymore information to help, just ask away.
Thank you for your time and help,
Luke H
I found the problem...I was using /vtkPointSource which generates random points and I was feeding in my points into that function. I am not sure why, but that made getting results out very difficult but once I passed in the correct information and placed a Reset() on the point Id array and the result Id array, it works like a champ. Hopefully this will same others some trouble because I spent some hrs working on this.
Luke H
vtkSmartPointer<vtkKdTreePointLocator> Tree =
vtkSmartPointer<vtkKdTreePointLocator>::New();
Tree->SetDataSet( Output );
Tree->BuildLocator();
vtkSmartPointer<vtkIdList> result =
vtkSmartPointer<vtkIdList>::New();
vtkSmartPointer<vtkIdList> point_ind =
vtkSmartPointer<vtkIdList>::New();
unsigned int k = 5;
double testpoint[3];
for( vtkIdType n = 0; n < Output->GetNumberOfPoints(); n++ )
{
Output->GetPoint( n,testpoint );
std::cout << "Point: " << testpoint[0] << ", " << testpoint[1]
<< ", " << testpoint[2] << ": " << endl;
Tree->FindClosestNPoints( k, testpoint, result );
for(vtkIdType i = 0; i < k; i++)
{
vtkIdType point_ind = result->GetId( i );
double p[3];
Output->GetPoint( point_ind, p );
std::cout << "Closest point " << i+1 << ": Point "
<< point_ind << ": (" << p[0] << ", " << p[1] << ", "
<< p[2] << ")" << std::endl;
}
result->Reset();
point_ind->Reset();
}