I'm getting a debug assertion error when I try to run my implementation of the Roman_int class exercise program. The debug assertion error is as I put in the title of this thread, "vector iterator not incrementable".
It's triggered from line 102 of this code in the <vector> header (line 9 here since I'm not bringing in the whole header):
The exercise doesn't say anything about reading from a file.
AFAI understand your program should be able to convert a roman number to an int, sth. like
Please enter a roman numeral: XIV
Roman numeral XIV equals 14 as int.
I know. The file is my way of getting the roman numerals so I don't have to type them all out into a vector on my own. It didn't work right, though. CL is being outputted as 451 as an int.
The file is my way of getting the roman numerals so I don't have to type them all out into a vector on my own.
Why do you need a vector? Do you do a different exercise?
Also it seems do don't understand to problem of converting a roman number to an int. A roman number is sth. like XIV and you need to find a way to produce the int 14.
I used a vector for the mapping. It's the same exercise. The output is correct right now. I'll look at that link after this post (I hope there's a better to convert a Roman numeral to an int shown in there). For now, I'll just post the code I have right now.
// chapter10ex6.cpp : Defines the entry point for the console application.
// Osman Zakir
// 2 /17 / 2017
// Bjarne Stroustrup: Programming: Principles and Practice Using C++ 2nd Edition
// Chapter 10 Exercise 6
// Exercise Specifications:
/**
* Define a Roman_int class for holding Roman numerals (as int s) 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';.
*/
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
#include <fstream>
#include "cust_std_lib_facilities.h"
class Roman_int
{
private:
std::string roman_num;
public:
int as_int(const std::string &roman);
const std::string &get_r_num() const { return roman_num; }
void set_r_num(const std::string s_val) { roman_num = s_val; }
};
std::istream& operator>>(std::istream &is, Roman_int &r);
std::ostream& operator<<(std::ostream &os, const Roman_int &r);
int main()
{
usingnamespace std;
cout << "Please enter a roman numeral within the range 1 through 300: ";
Roman_int r;
cin >> r;
cout << "Roman numeral " << r << " as an int is "
<< r.as_int(r.get_r_num()) << '\n';
keep_window_open();
}
int Roman_int::as_int(const std::string &roman)
{
usingnamespace std;
cout << "Please enter input file name: ";
string iname;
cin >> iname;
ifstream ist{ iname };
try
{
if (!ist)
{
error("can't open input file ", iname);
}
}
catch (const runtime_error &e)
{
std::cerr << "error: " << e.what() << '\n';
}
vector<string> roman_nums;
string num;
while (getline(ist, num))
{
roman_nums.push_back(num);
}
int arabic_num = 0;
for (size_t i = 0; i < roman_nums.size(); ++i)
{
if (roman == roman_nums[i])
{
arabic_num = i + 1;
}
}
return arabic_num;
}
std::istream& operator>>(std::istream &is, Roman_int &r)
{
usingnamespace std;
string roman_s;
is >> roman_s;
r.set_r_num(roman_s);
return is;
}
std::ostream& operator<<(std::ostream &os, const Roman_int &r)
{
os << r.get_r_num() << '\n';
return os;
}
I took the overloads for error() and keep_window_open() and put them into a custom header. If you think I should also add some other stuff from std_lib_facilities.h as well, please let me know. I'm using VS2015 and apparently Microsoft doesn't support C++11 inheriting constructors according to a comment Stroustrup added to the header file here:
1 2 3 4 5 6 7 8 9 10 11
#ifdef _MSC_VER
// microsoft doesn't yet support C++11 inheriting constructors
Vector() { }
explicit Vector(size_type n) :std::vector<T>(n) {}
Vector(size_type n, const T& v) :std::vector<T>(n,v) {}
template <class I>
Vector(I first, I last) : std::vector<T>(first, last) {}
Vector(initializer_list<T> list) : std::vector<T>(list) {}
#else
using std::vector<T>::vector; // inheriting constructor
#endif
Does this still apply? Should I keep this in my custom header, too?
Edit: Alright, thanks for giving me that link. I used the functions from that and it works much better. Why is my output on two separate lines, though? When I say cout << "Roman numeral " << r << " as an int is " << r.as_int(r.get_r_num()) << '\n'; the result is
Roman numeral <insert Roman Numeral here>
as an int is <insert int value here>
Why is my output on two separate lines, though? When I say cout << "Roman numeral " << r << " as an int is " << r.as_int(r.get_r_num()) << '\n'; the result is
You have one '\n' in your output operator as well.