Monday, 17 February 2020

Chapter 10 // Exercise 8 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h

Chapter 10 // Exercise 8

Write a program that accepts two file names and produces a new file that is the contents of the first file followed by the contents of the second; that is, the program concatenates the two files.


Ah, a nice and easy one. I also really love using substr(), it has so many useful applications, like checking to see if a certain part of a string matches another string. I also found that you can easily copy files into another by using the .rdbuf() function. It contains a pointer to the contents of the file for easy access.

Saturday, 15 February 2020

Chapter 10 // Exercise 7 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h

Chapter 10 // Exercise 7

Make a version of the calculator from Chapter 7 that accepts Roman Numerals rather than the usual Arabic ones, for example, XXI + CIV == CXXV.


When I first tried this I realised we needed a way to convert Roman Numeral to Ints so went back to the previous exercise and added a new function that does that. Then it became as simple as adding the class to the file and checking input for roman numerals. Once they are all added, they are then converted to an int, the calculations are done and then the resulting int is converted back to a Roman Numeral.

Saturday, 18 January 2020

Chapter 10 // Exercise 6 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h

Chapter 10 // Exercise 6

Define a Roman_int class for holding Roman numerals (as ints) with a << and >>. Provide Roman_int with an as_int() member that returns the int value, so that if r is a Roman_int , we can write cout << "Roman" << r << " equals " << r.as_int() << '\n';


This exercise was quite confusing. He mentions to store the values in Roman_int as ints but then use a member function called as_int() to return the integer value of the int??? Surely it would make more sense to input the values as chars like C or M and then use the as_int() function to output 100 or 1000.

Eventually I decided upon a class that stores an int but when using cout<< it returns the roman numeral comversion. This turned out to be harder than I thought. The main problem comes from the adding/subtracting depending what side of the main number you're on. My first few attempts ended up with a lot of ifs and switches but if there's one thing I've learnt in my job as an engine programmer, it's to avoid branching as much as possible. So I scoured the internet in search of a more optimal solution.


This smartly uses modulo and divide to correctly determine where the number is in the number table. For example if you input 618, the divide will be 0 for the first 2 loops (and therefore there will be nothing to print). However 618 / 500 is 1, therefore the corresponding symbol will be printed that matches the index of the table. This is what I was trying to attempt but I kept messing up the division and remainders.

.....*sometime later*

When attempting the next exercise I quickly realised that the class needed a way to convert roman numerals to ints. I thought that this would be pretty simple however there is the rule that if the following number is greater than the previous then you subtract. Numerous examples on the internet were either in Python (eurgh) or contained a great deal of branching. I'm quite proud of the small function that I came up with.

Wednesday, 15 January 2020

Chapter 10 // Exercise 5 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h

Chapter 10 // Exercise 5

Write the function print_year() mentioned in section 10.11.2.


Oh I detested this exercise. It wasn't necessarily hard; the format just made it very confusing. Also, having a vector, in a vector, in a vector almost blew my brains out. I honestly think he made this more complicated than it needed to be just to make you think. The problem is though that you will probably see code like this "in the wild". 

In the first chapters of this book, Bjarne mentions the importance of avoiding magic numbers. However, if you check out PrimitiveComponent.cpp in Unreal Engine 4.10, you'll find this magical snippet:

 int32 UPrimitiveComponent::CurrentTag = 2147483647 / 4;

On a code review a senior thought I had done this; I didn't, it was already there. I asked my manager why they would do this and he asked me why that number was special; I had no clue. He then informed me it was the largest number you can fit in an int32. However, he was confused as to why they didn't just use MAX_INT or const instead of some ridiculous magic number.

Tuesday, 14 January 2020

Chapter 10 // Exercise 4 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h

Chapter 10 // Exercise 4

Modify the store_temps.cpp program from exercise 2 to include a temperature suffix c for Celsius or f for Fahrenheit temperatures. Then modify the temp_stats.cpp program to test each temperature, converting the Celsius reasdinfs to Fahrenheit before putting them in the vector.


It was in this exercise that I realised I had goofed the median bit and accidentally left in out of bounds errors (I also forgot to add a check for if the vector contained 1 value). I decided to add some more error checking as well as whilst re-doing the book I became quite lax and focused more on getting the exercises done than adding code that was actually robust.

I also prefer my new "isNumber()" function over the previous one that I used to use all the time. I think allowing cin to fail and then clearing it is a lot more of a hassle than just reading into a string. Cin will never go bad and you can just use the extremely handy "find_first_not_of()" function found in the std library. I love that function. This also allows for some easy parsing to extract numbers and characters.

Another thing I learnt whilst doing this exercise is that when using while(!file.eof) and ctrl+z, the last line will actually be read twice before the eof is read. This is not great if you are pushing things back into vectors. I kept getting an extra value and wondered where it was coming from. Instead, I'll remember to always start the while loop with while(cin >> value) as the eof will be read immediately.