LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-25-2018, 09:43 PM   #1
TheEzekielProject
Member
 
Registered: Dec 2016
Distribution: arch
Posts: 668

Rep: Reputation: 190Reputation: 190
Why doesn't this program terminate properly? c++


Hello all,

I am teaching myself C++ with the help of Programming Principles and Practice Using C++ by Bjarnes Stroustrup but I am having trouble with a drill exercise.


The step of the drill is to create a program in which you enter two numbers and the program states which is smaller and which is larger, or if they are equal. And it is supposed to terminate on entering the '|' character.


The program works so far, except for when entering the '|' character, it infinitely repeats the last larger/smaller lines e.g.
Code:
23 is the smaller number.
32 is the larger number.
23 is the smaller number.
32 is the larger number.
23 is the smaller number.
32 is the larger number.
23 is the smaller number.
32 is the larger number.
23 is the smaller number.
...
I'm sure I'm missing something simple. But I can't quite figure out what! A hint in the right direction would be appreciated


Code:
#include <iostream>
#include <cmath>
#include <vector>
#include <string>

int main ()
{
    double x, y;
    std::cout <<"Enter 2 integers, terminate with '|'\n";
    std::cin>> x >> y;
    while(x !='|' && y != '|')
    {

        if(x<y)
            std::cout << x <<" is the smaller number.\n" << y <<" is the larger number.\n";
        else if(y<x)
            std::cout << y <<" is the smaller number.\n" << x <<" is the larger number.\n";
        else if(x==y)
            std::cout <<"The numbers are equal.\n";
        std::cin >> x >> y;
        
    }
    return 0;

}
 
Old 10-25-2018, 10:08 PM   #2
Mechanikx
Member
 
Registered: Jul 2018
Distribution: Slackware
Posts: 351

Rep: Reputation: 258Reputation: 258Reputation: 258
You've declared 'x' and 'y' to be of type double. '|' is a char.

If I change your while statement to:

while(x != 0 && y != 0)

for instance, it terminates appropriately.
 
Old 10-25-2018, 10:15 PM   #3
TheEzekielProject
Member
 
Registered: Dec 2016
Distribution: arch
Posts: 668

Original Poster
Rep: Reputation: 190Reputation: 190
Thank you for pointing that out!
The exercise requires that I use '|' so I suppose I will have to find another way.
 
Old 10-25-2018, 10:30 PM   #4
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,871
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
You could use fgets to read a line, remove the terminating \n character, then compare the content with "|".
Then try sscanf (fmt "%lf %lf") to read two double values from the linlineffer - if it doesn't return 2, then warn the users.
 
Old 10-25-2018, 10:34 PM   #5
TheEzekielProject
Member
 
Registered: Dec 2016
Distribution: arch
Posts: 668

Original Poster
Rep: Reputation: 190Reputation: 190
Quote:
Originally Posted by NevemTeve View Post
You could use fgets to read a line, remove the terminating \n character, then compare the content with "|".
Then try sscanf (fmt "%lf %lf") to read two double values from the linlineffer - if it doesn't return 2, then warn the users.



I am only on the 4th Chapter of the book and have not learned about those. I am assuming I am supposed to find a way to accomplish the task only with what has been taught so far.


But thank you for the suggestion!
 
Old 10-25-2018, 10:46 PM   #6
Mechanikx
Member
 
Registered: Jul 2018
Distribution: Slackware
Posts: 351

Rep: Reputation: 258Reputation: 258Reputation: 258
Quote:
Originally Posted by TheEzekielProject View Post
I am only on the 4th Chapter of the book and have not learned about those. I am assuming I am supposed to find a way to accomplish the task only with what has been taught so far.


But thank you for the suggestion!
In that case you can declare 'x' and 'y' to be of type 'char' that way you can store a '|' in either of them during runtime. The only difference is you'll now be comparing the characters '23' and '32', for example.

EDIT: This is incorrect. It will only properly compare single character digits. Sorry, it's been a long day.

Last edited by Mechanikx; 10-26-2018 at 12:51 AM. Reason: Correcting a mistake once I was able to test possible solution.
 
Old 10-25-2018, 10:48 PM   #7
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,871
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
Well, these functions/ways are considered to be 'old fashioned' by some C++ programmers, so you might not read about them in Stroupstrup's book.
A note: at this level it might be completely enough to exit when the reading of a number fails (see cin.fail())
 
Old 10-25-2018, 10:54 PM   #8
TheEzekielProject
Member
 
Registered: Dec 2016
Distribution: arch
Posts: 668

Original Poster
Rep: Reputation: 190Reputation: 190
Quote:
Originally Posted by Mechanikx View Post
In that case you can declare 'x' and 'y' to be of type 'char' that way you can store a '|' in either of them during runtime. The only difference is you'll now be comparing the characters '23' and '32', for example.



The directions for this part requires that I use 'double'


Quote:
1. Write a program that consists of a while-loop that (each time around the loop) reads in two ints and then prints them. Exit the program when a terminating '|' is entered.
2. Change the program to write out the smaller value is: followed by the smaller of the numbers and the larger value is: followed by the larger value.
3. Augment the program so that it writes the line the numbers are equal (only) if they are equal.
4. Change the program so that it uses doubles instead of ints.
 
Old 10-26-2018, 01:05 AM   #9
Mechanikx
Member
 
Registered: Jul 2018
Distribution: Slackware
Posts: 351

Rep: Reputation: 258Reputation: 258Reputation: 258
I remember doing a project similar to this one when I was learning C. You had to write a program that functioned like an accumulator. So, you would enter a number then an arithmetic symbol to operate on the total amount stored. The input was 'int' 'char'. Where 'char' was the arithmetic symbol or 'E' to exit.
 
Old 10-26-2018, 01:05 PM   #10
Beryllos
Member
 
Registered: Apr 2013
Location: Massachusetts
Distribution: Debian
Posts: 529

Rep: Reputation: 319Reputation: 319Reputation: 319Reputation: 319
I am not an expert in C++, but I gather that you could define a class which can contain either double or char, and define corresponding methods for input and comparison. I have never done that, but it is possible, right?
 
Old 10-26-2018, 03:00 PM   #11
TheEzekielProject
Member
 
Registered: Dec 2016
Distribution: arch
Posts: 668

Original Poster
Rep: Reputation: 190Reputation: 190
Just in case anyone is interested I think I'm making progress
Code:
#include <iostream>
#include <cmath>

int main ()
{
	int x, y;
	std::cout <<"Enter 2 integers, terminate with '|'\n";
	while(std::cin >> x >> y)
	{

		if(x<y)
			std::cout << x <<" is the smaller number.\n" << y <<" is the larger number.\n";
		else if(y<x)
			std::cout << y <<" is the smaller number.\n" << x <<" is the larger number.\n";
		else if(x==y)
			std::cout <<"The numbers are equal.\n";
	}
	return 0;

}
Right now it terminates on any non int character. But I think it's a start in the right direction

Last edited by TheEzekielProject; 10-26-2018 at 03:02 PM.
 
Old 10-26-2018, 03:29 PM   #12
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,269
Blog Entries: 24

Rep: Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196Reputation: 4196
Quote:
Originally Posted by TheEzekielProject View Post
Just in case anyone is interested I think I'm making progress
Code:
#include <iostream>
#include <cmath>

int main ()
{
	int x, y;
	std::cout <<"Enter 2 integers, terminate with '|'\n";
	while(std::cin >> x >> y)
	{

		if(x<y)
			std::cout << x <<" is the smaller number.\n" << y <<" is the larger number.\n";
		else if(y<x)
			std::cout << y <<" is the smaller number.\n" << x <<" is the larger number.\n";
		else if(x==y)
			std::cout <<"The numbers are equal.\n";
	}
	return 0;

}
Right now it terminates on any non int character. But I think it's a start in the right direction
Of course that is not in line with the previous instructions...

Quote:
Originally Posted by TheEzekielProject View Post
The directions for this part requires that I use 'double'
But the whole point of such exercises is to get you to explore the territory, the best way to learn, so all variations can be informative!

Considering the problem of doing it with doubles, using "|" as the only termination character is an interesting exercise, no doubt why it was included!

Think about it this way: Your first task was to use integer types which presumably resulted in your code structure. The termination test was a natural fit in that case - you didn't have to think about it too much. Then they asked you to use doubles for the numeric types, which produces the apparent "conflict" with the termination character comparison - but only because you already wrote everything usiing integers! Now you have to think about how to accept and compare numeric input or character input, without knowing which it will be in advance. Stringstream comes to mind.

Good luck!
 
Old 10-26-2018, 05:03 PM   #13
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Quote:
Originally Posted by TheEzekielProject View Post
The directions for this part requires that I use 'double'

Quote:
1. Write a program that consists of a while-loop that (each time around the loop) reads in two ints and then prints them. Exit the program when a terminating '|' is entered.
2. Change the program to write out the smaller value is: followed by the smaller of the numbers and the larger value is: followed by the larger value.
3. Augment the program so that it writes the line the numbers are equal (only) if they are equal.
4. Change the program so that it uses doubles instead of ints.
that is line 4 that you are to use doubles, this is having you going one step at a time, your use of double code should already have the '|' figured out in how to do that while using int for your numbers. whereas I do not see this in your code.

try this, its in need of cleaning up, but... it works for me..
Code:
#include <iostream>
#include <cstdlib>
#include <cstring>

int main ()
{
  char x1[2];
  char y1[2];
 
std::cout <<"Enter 2 integers 0 - 9 , terminate with '|'\n"; 
    
    for (;;)
    {
            std::cout<<"enter 1st number\n";
            std::cin>> x1 ;
      // feed back to see what I am working with
        std::cout<<x1[0]<<std::endl;
	std::cout<<" compare "<<strcmp("|", x1)<<std::endl;
            
             if ( strcmp("|", x1) == 0)
	          return 0;

	 std::cout<<"enter second number : ";
	 std::cin >>y1;

         //is int because that is what is returned
         // so it meets the requirement of the assignment
	 auto x = atoi(x1);
	 auto y = atoi(y1);
	
         if ( x == y )
	     std::cout<<x<<" is equal to "<<y<<std::endl;
	 else if ( x > y )
             std::cout<<x<<" is larger than " <<y<<std::endl;
	 else
	     std::cout<<x<<" is lesser than "<<y<<std::endl;
      }
      return 0;
}
stop and think it through first so you can build on your programming logic.

you where taking in both, one after then other, and only need to check for the first one, first to see if that meets the requirements to stop the program, if no, then take in second data type, then proceed with what ever you need to do.

your 'if statements too' it is process of elimination logic
Code:
    if(x<y)
	std::cout << x <<" is the smaller number.\n" << y <<" is the larger number.\n";
    else if(y<x)
	std::cout << y <<" is the smaller number.\n" << x <<" is the larger number.\n";
    else if(x==y)
	std::cout <<"The numbers are equal.\n";
that is not applying that logic. it is,
Code:
if
else if
else

Last edited by BW-userx; 10-26-2018 at 06:29 PM.
 
Old 10-28-2018, 05:33 AM   #14
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Quote:
Originally Posted by TheEzekielProject View Post
The directions for this part requires that I use 'double'
Not quite. It requires that you read two numbers but it doesn’t say you need to read them directly to a variable of wanted type. In fact, if pipe character is the only thing that terminates the program, you must read the data into a string first. To do that, declare a std::string buf and then do std::cin >> buf. You can then inspect the value to detect whether it’s a pipe character. If it is – terminate, if it’s not – try to convert the value to a number with strtol or strtod which will let you detect when an invalid value is entered. Here’s one approach which loops when incorrect value is entered and reads the next one (alternative would be to terminate on any error):

Code:
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>

static int read_long(long *value) {
	for (std::string buf; std::cin >> buf; ) {
		if (buf == "|") {
			return 0;
		}
		errno = 0;
		char *end;
		long ret = strtold(buf.c_str(), &end);
		if (*end || (errno && errno != ERANGE)) {
			std::cerr << "Expected integer or '|', got "
			          << buf << '\n';
		} else if (errno == ERANGE) {
			std::cerr << "Value too large\n";
		} else {
			*value = ret;
			return 1;
		}
	}
	return -1;  /* EOF */
}

int main() {
	for (;;) {
		long x, y;
		int ret = read_long(&x);
		if (ret < 1) {
			return -ret;
		}
		ret = read_long(&y);
		if (ret < 1) {
			return -ret;
		}
		if (x == y) {
			std::cout << "The numbers are equal.\n";
		} else {
			std::cout << (x < y ? x : y)
			          << " is the smaller number; "
			          << (x < y ? y : x)
			          << " is the larger number.\n";
		}
	}
}
Perhaps a more interesting problem would be to support numbers of arbitrary length. For integers it’s relatively simple problems. For real numbers it gets a little bit trickier though not too bad if one chooses not to support exponent format.
 
1 members found this post helpful.
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to terminate a gfortran program? AlexBB Linux - Newbie 6 05-06-2014 06:27 AM
how to terminate dispatch.fcgi process properly sathiyamoorthy Debian 0 02-26-2008 11:20 PM
Program doesn't run properly on boot KenPem Programming 8 12-27-2007 04:42 PM
Terminate Hung Program Ingla Linux - General 3 11-15-2005 08:13 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:44 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration