Help with a very beginner question

I'm trying to help my friend (who is new at programming) write a program whose guidelines are laid out as follows...
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.

After looking at this and looking at the tools he was taught thus far, I was surprised to find that I couldn't actually solve this myself. Does anyone have any idea?

The tools that have been taught thus far are as follows:
-casting
-while loops
-if statements
-functions
-variables
-primitive types (and operations)
-vectors (arrays)
-switch statements
-probably a few others I'm forgetting.

How would someone of this level write the given program?

Note* Tokenizing is not an option because classes have not yet been introduced, nor has the boolean functions "ispunct()" and "isdigit()".
Last edited on
My only thought is to terminate on input error.

1
2
3
while (cin >> n1 >> n2)  // terminates when anything that isn't a number is input
{
}


It just seems like that sort of thought process is too complicated for new programmers, but that would work :/. However, the book specifically asks for '|' as a terminator.
Last edited on
Without being permitted to use a stringstream or the like...
You can always skip whitespace and peek:

1
2
3
4
5
6
7
8
while (true)
{
    cin >> ws;
    if (cin.peek() == '|') break;
    cin >> n1 >> n2;
    if (!cin) foo_anyway();
    ...
}

Also, sorry about the 'reported' tag... some loser has decided that it is his personal journey in life to report all my posts.
you should look at the ascii table so you know what is the decimal value of | . then simply get an integer and compare it with the integer value of | to break.
then simply get an integer and compare it with the integer value of | to break.
Will not work. Integer input will not read a non-digit. Also it would have some undesireable behavior of breaking on numbers equal to character code of '|'
closed account (48T7M4Gy)
This is the obvious answer and I'm sure I haven't made any sort of a programming breakthrough. What I'd like to now know is where the difference lays:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>

using std::cin;
using std::cout;

int main()
{
    char ch = 'x';
    
    int a = 0, b = 0;
    
    
    while( ch != '|')
    {
        cout << "First number: ";
        cin >> a;
        
        cout << "Second number: ";
        cin >> b;
        
        cout << a << '\t' << b << '\n';
        
        cout << "Where to now? ";
        cin >> ch;
        
    }
    return 0;
}
Last edited on
@kemort judging by OP post, input should be in form of "300 356 74 10 |".
Your code will eat '7' from 74 and read 4 instead.
closed account (48T7M4Gy)
@ MiiniPaa - Yeah, input has to be something like that. Mine's too good to be true. That's why I hedged my bets. :) But there again mine satisfies the conditions unless I'm mistaken.

As far as character eating, my program is running on MBPro OSX with Xcode latest performs perfectly without loss - but maybe I'm just a lucky.
http://coliru.stacked-crooked.com/a/597bc0582d03c25c
http://ideone.com/OmSOz6
http://rextester.com/ZHJL37250

As you can see, all major compiler behave the same way and eat first digit of first number in second and following sets.
closed account (48T7M4Gy)
First number: 74
Second number: 340
74	340
Where to now? l
First number: 56
Second number: 79
56	79
Where to now? |
 
Exit code: 0 (normal program termination)


I couldn't get the results on your compilers because I'm not too familiar with the interfaces but I saw your output and don't doubt your words.

But the fact is I run it on the shell here and my machine and that's what I get my friend. All I can say is we'll have to ring up Tim Cook and tell him. He's in for a shock by the sound of it.

PS

Just to make sure there is no magic in the numbers:
First number: 300
Second number: 356
300	356
Where to now? n
First number: 74
Second number: 10
74	10
Where to now? |
 
Exit code: 0 (normal program termination)
Last edited on
Where to now? l
You are not supposed to enter anything but numbers and | at the end.
Program should work when fed, for example, folowing file as input:
123 456 789 1011 
1213 1415 |


I forgot to mention why I know format of input. This is Drill 1 of chapter 4 of Programming: Principles and Practice Using C++
Last edited on
closed account (48T7M4Gy)
Yeah I know.

I since had another look at your interfaces/compilers where, I agree, you are presenting a stream of data instead of discrete chunks via the various cin statements which is what I am doing. I think we both knew that difference existed right at the start.

The problem is the problem specification says you can't tokenize or whatever. I have taken this as meaning that you can't present a stream of data and why I came up with what I pointed out at the start is really a trivial, but the only in my estimation, alternative.

Maybe the guy has set an impossible task. He thought so.

Tim Cook can breathe a sigh of relief that his empire is safe.

PS Maybe the key is a stream reader and barebones Turing machine. But by what I read from you now 'return' is unacceptable so you read the string in and cut the power maybe? Or cut the paper tape if scissors are allowed - he dosen't say they aren't.
Last edited on
closed account (48T7M4Gy)
I forgot to mention why I know format of input. This is Drill 1 of chapter 4 of Programming: Principles and Practice Using C++


LOL - late breaking news
Well, I don't know the book, but the simplest solution still is to simply quit on any invalid character:

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;

int main()
{
  int a, b;
  while (cin >> a >> b)
  {
    cout << "(" << a << "," << b << ")\n";
  }
}

If you really want to check that it was a pipe character, you can do that too:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <ciso646>
#include <iostream>
using namespace std;

int main()
{
  int a, b;
  while (cin >> a >> b)
  {
    cout << "(" << a << "," << b << ")\n";
  }
  
  if (!cin.eof())
  {
    cin.clear();
    char c = cin.get();
    if (!cin or (c != '|'))
      cout << "Hey, you didn't end with '|'!\n";
  }
}

You could buffer the input a bit by using a stringstream, but this really does exactly the same thing as the first example above:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main()
{
  string s;
  getline( cin, s, '|' );
  istringstream ss( s );
  int a, b;
  while (ss >> a >> b)
  {
    cout << "(" << a << "," << b << ")\n";
  }
}

Again, you can check to see if a '|' was really encountered or not:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main()
{
  string s;
  getline( cin, s, '|' );
  istringstream ss( s );
  int a, b;
  while (ss >> a >> b)
  {
    cout << "(" << a << "," << b << ")\n";
  }
  
  if (cin.eof())
  {
    cout << "Hey, you didn't end with '|'!\n";
  }
}

Anyway...
Technically, at this point it is expected that you should terminate at any non-numeric input, but '|' is the documented and "proper" way.

The quote from a book, explaining how looping on input works, and how you are expected to stop numeric input (for now)
Basically, cin>>temp is true if a value was read correctly and false otherwise, so that while-loop will read all the doubles we give it and stop when we give it anything else. For example, if you typed
1 .2 3.4 5.6 7.8 9.0 |
then temps would get the five elements 1 .2, 3.4, 5.6, 7.8, 9.0 (in that order, for example, temps[0]==1.2) . We used the character '|' to terminate the input - anything that isn't a double can be used. In ยง10.6 we discuss how to terminate input and how to deal with errors in input.
closed account (48T7M4Gy)
As contributed above, in the absence of any evidence otherwise it seems the winner is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

using std:: cout;
using std::cin;

int main()
{
  double a, b;
  
   cout << "Start\n";

  while (cin >> a >> b)
       cout << a <<  '  ' << b << '\n';

}


http://people.ds.cam.ac.uk/nmm1/C++/Exercises/Chapter_04/ is one reliable source without Stroustrup saying much on the topic.

It appears that the purpose of the drill was to demonstrate the while loop primarily and one simple way to get out of the loop, albeit that non-double input terminates the program.

But there is nothing to say '|' must be the only terminator.

The program satisfies all the problem specifications, without fail.
Last edited on
Topic archived. No new replies allowed.