C++ Logo

std-proposals

Advanced search

Making C++ easier for new students

From: Bill Kerney <bkerney_at_[hidden]>
Date: Tue, 3 Aug 2021 06:05:07 +0000
Hi all,

I've been watching this list for a while, and as a college instructor who teaches C++, I was curious how much interest this group has in making the introductory C++ experience easier for new students. It seems like something that would be good for the language as a whole in the long term, but I rarely see a proposal here that would make life better for my first semester students.

After having taught C++ since, hmm, I guess technically 1997, but full time as a faculty member since 2015, I can relate to you all the questions I get asked which don't have a very good answer in the language and standard library:


  1. How do I do non-blocking I/O? (Sometimes phrased like, "How do I read an arrow key?")
  2. How do I recover from errors in input?
  3. How do I display graphics on the screen?
  4. How do I do colored text?
  5. How do I read a mouse click?
  6. How do I play a sound?
  7. How do I send data over the internet?
  8. How do I split a string?

It's not all bad. Some areas that have gotten better over the years are multithreading, strings, and memory safety. When I first started teaching C++ in 1997, it was unusual for students to write code that didn't leak or crash or corrupt memory. Now, since I teach them to use vectors (or other standard containers) and smart pointers, it's actually very unusual for address sanitizer (which I have turned on for them by default) to detect any problems outside of them trying to write a container class.

I've written solutions to 1, 2, 4, and somewhat to 5. I mentioned a couple weeks ago I don't think my colors library (which does 1,3, and 5) isn't designed to be added to a standard library, but I've been my read library (https://github.com/ShakaUVM/read) in my classes for a couple years now, and it really does makes learning C++ a lot easier, with no loss of power.

For example, when you normally read an int from cin or a file or whatever, there's the simple way:
int apples;
cout << "Please enter how many apples you want to buy:\n";
cin >> apples;

But the simple way that we teach students is actually bad. Apples wasn't initialized (we could initialize it, but the initialized value wouldn't be used), it doesn't do any error handling, it doesn't reprompt and retry if something goes wrong, and if something does go wrong (like the user types in a non-integer) then every cin statement after that point fails. Experienced programmers know how to handle this, but new programmers don't. Instead, they will just be mystified when text starts scrolling up their screen as every cin statement is skipped.

So you can teach them the more robust way of reading an int from the keyboard, handling the various errors and reprompting, and then it ends up looking something horrific like this:

int apples = 0;
while (true) {
       if (cin.eof()) {
            break;
        }
        cout << "Please enter how many apples you want to buy:\n";
        cin >> apples;
        if (cin) {
            break;
        }
        cin.clear(); //Clear error code
        std::string s;
        cin >> s; //Or use cin.ignore()
}

When I show this to first semester students, and tell them they need to do this every time they read an int, they go cross-eyed, and decide to just not worry about error handling, which is a really bad habit to get into.

So I wrapped it up into a function and templated it, and with some contributions from people on Reddit, had it do type deduction so they don't need to use <> to use it.

By contrast to the above, they just need to type this in my class:

int apples = read("Please enter how many apples you want to buy:\n");

It works with files as well, so if you want to read a double from a file named ins, you just do this:

double elevation = read(ins);

And that's it. One line of code, it handles errors, it plays nicely with my version of getline (normally cin and getline cause trouble when used together due to trailing newlines in the input buffer), it works with classes with an operator>> overload for them:

Triangle t = read();

And you can even read into consts, which is something you can't directly do with iostreams, since iostreams is all call by reference:

const X_SIZE = read(ins), Y_SIZE = read(ins); //Read the maximum X and Y sizes from disk and store in a const

In the last thread on colored text, some people rightfully said that a lot of applications don't use text any more, which is completely correct, but if you look at the example code that everyone uses on cppreference and other sites, it still all uses iostreams, since, well, that's the standard. And even if you don't use console I/O, reading and writing to files is still common. So I think it'd be really nice if the standard made doing input, correctly, easy.

If we make C++ easier for the next generation, then this will help C++ grow over the years.

Thanks for your time,
Bill Kerney
Clovis Community College

Received on 2021-08-03 01:05:16