Need help saving a vector to a file

Pages: 12
To check if I'm at least beginning to understand what's going on...

An Orthography is a set of mappings.
A CharacterMatch is a mapping from one string fragment (1-3 characters) to another.

Are the mappings (CharacterMatchs) in a Orthography from a single source?

Do you apply a single Orthography to a given document at a time, or can multiple sets of mappings be applied to the same document?

Andy

PS The saving code still holds. Except another lavel is needed. You could either same each Orthography in its own file, or you could save then in a single file by adding some kind of header lines.

The easiest approach would be to write "Orthography Name" followed by the Character matches on the following rows, ending with a blank like of the end of the file. If another line beginning with "Orthography" is found, you repeat the process. So the code to read the vector in can still be used, but need a loop which looks for lines beginning with Orthography, creates a new instance of the orthography class, and then calls it to load the CharacterMatchs into the vector (the save'ToFile and read'FromFile functions are now methods on Orthography which load CharacterMatchs.)
Last edited on
Yes, the way you put it (an Orthography being a set of mappings with the mappings themselves being CharacterMatch objects) is correct. And yes, the mappings in an Orthography are from a single source. Right now I have them hard-coded in but I am currently working on making them flexible so users can add their own orthographies, give them names, add CharacterMatches, etc.

They are used to help rewrite old historic material into a writing system that we are more familiar with. These historic systems aren't so off the wall that we can't make sense out of them but rather I'm wanting to have this as a tool to help us see possible spelling variations that we may not notice just by reading them. And in doing so, help us translate the material.

For example, an historical document may need very few changes. Such as:

"a" becomes an "e"
"e" becomes an "i"
"h" becomes an "x"

etc, etc.

Some systems need quite a few more. And to answer your question, a single orthography will be used at a time since that particular orthography will be used for that specific historic document.

Your mention of applying an orthography to a document has me intrigued. As of right now it is just parsing what you type into the edit box. I have no idea how to go about applying it to a document. Are you talking about a Word document or PDF file?

Your approach of using a single file for all orthographies is the route I'd like to go. I've just never done anything like this before so this is all new to me. I understand enough of coding to sort of understand what you are trying to do but I don't have the knowledge/experience to make it happen.
a single orthography will be used at a time
Your approach of using a single file for all orthographies is the route I'd like to go.

If you're using a single orthography for document, saving the orthographies in their own files seems the better fit to me.

Your mention of applying an orthography to a document has me intrigued

I was using "document" in a loose sense; the text of the document.

But processing a text file would be easy enough (you've seen the code in the test I posted, which can read and write Unicode text.)

Processing the text in Word documents and PDF files is possible, but would be rather harder to implement.

Andy
Right now, my program uses hard-coded orthographies that are available via a drop-down menu. I can also create new orthographies and they will add themselves to the drop-down menu. And I can add character matches (CharacterMatch) to them. It works great! The only trouble is being able to save them to a file (which is why I started this thread). What I am unsure of is how to implement the code you have posted into my program and/or what code I need to show you to point me in the right direction to get rolling.

So you think separate files for each orthography? That is fine by me so long as the orthography names can be loaded from each file for the drop-down menu and fully loaded when that name is selected. The reason being is that I may use one orthography or a handful of words but then need to use another when I need to work with another source.

And as far as doing actual Word or PDF files...I'll save that for MUCH later LOL :).
What I am unsure of is how to implement the code you have posted into my program and/or what code I need to show you to point me in the right direction to get rolling.

If you're first post in this thread is to a static member of Orthography, then that's a good enough starting point.

The code I posted before needs to be changed so it uses CharacterMatch instead of Orthography and then made a member of the Orthography class which takes an ostream& instead of the filepath (the same file stream is passed to each Orthography in turn.

The Orthography class needs to be extended so it can save itself. This method should also take an ostream. The save method need to write a header of some sort to the file, then call the function that saves the CharacterMatch vector, and then write a foot line. The load method needs to follow the sae pattern but with reading.

I would prob make LoadOrthographies and SaveOrthographies global functions, or members of your app window, rather than static members of the Orthography class.

So you think separate files for each orthography?

The reason I think this is that you might want to be able to group the text document with the orthography used on it. From a versioning point of veiw, this might help in the long run. You can then alter a given orthography later without affecting earlier work.

It is probably a bit more work, so maybe it should be left for now, and a single file used instead. After all, a file format which can store multiple orthographies can also store a single one.

Talking of future proofing, rather than using a custom file format, I would consider using JSON, YAML, or XML. Or even the ini-file approach I suggested in an earlier thread.

Andy

After XML, JSON: Then What?
http://www.drdobbs.com/web-development/after-xml-json-then-what/240151851
Last edited on
Ok, I've spent the past few days trying to figure out more of your code. I am not sure if your code was trying to do something different than I intended or if it is just a bit too advanced for me. There is a lot about it that I don't understand and I can't tell what's going on. And if your code is doing something different than what I was after, that also might be why I am having a hard time understanding it because my mind may be trying to see my intent in your code.

But near as I can tell, your code for an Orthography only consisted of 2 data members which were arrays (of size 8) and that is it. So in essence, your code for an Orthography consisted of two strings. If so, that sounds like what I intended for my CharacterMatch class. And if that was your intent and you said that my code needs to be changed over to include CharacterMatches, I am assuming you would think it would be a good idea for my CharacterMatches class to have 2 array data members (of size 8) rather than wstrings, right?

And once that is done, my Orthography class would then be a collection of these CharacterMatches (which was my original intent), right?

Just trying to make sure I am understanding this right :).

Then I need to take your suggestion of extending the Orthography class so it can save itself. You also suggested making the LoadOrthography and SaveOrthography functions global. What I am currently doing is declaring my Orthography object as a global object in my program. So if I put LoadOrthography and SaveOrthography in my Orthography class and that Orthography object is global, would that serve in the capacity of you recommending that it be global? Or is that a bad practice?

I'll worry about saving and loading here in a bit. Right now I think I have an idea on how these classes need to be set up. I'll post the code in a bit.
Ok, I've been working on my CharacterMatch and Orthography classes. For the most part I have them working as they did before but this time around I am using your arrays. But again I am stuck at my original problem which is I don't know how to go about saving this to a file. My experience in saving to a file is limited to the book I mentioned in the beginning of this post which is pretty much useless based on the responses I've gotten. And unfortunately I know very little as far as what is going on with the code examples that have been posted. With that being the case, it is hard to "run with it".

I've also been tweaking my classes to make them easier to work with in my program. But I'm also having a problem that I can't figure out. I've added an m_Name wstring variable to my CharacterMatch class. I am wanting to use it as a quick means to locate a CharacterMatch in an orthography when I want to delete it. The problem is that when I "push_back" a new CharacterMatch, the m_Name variable of that CharacterMatch is not included for some reason. Stepping into the program shows me that all the data members are created but again for some reason, that m_Name isn't included when I add it to an orthography.

Here is my code so far. Note that I also have a few things on my "to do" list like running a check to make sure that a user can't add duplicate CharacterMatch entries.

CharacterMatch.h
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#ifndef CHARACTER_MATCH_H
#define CHARACTER_MATCH_H

//=====================================================
// Includes
//=====================================================
#include <string>
#include <array>
#include <algorithm>
using namespace std;


template<size_t N, class V>
array<wchar_t, N> toArray(const V& v)
{
    array<wchar_t, N> d = array<wchar_t, N>();
    copy(begin(v), end(v), begin(d));
    return d;
}

class CharacterMatch
{
public:
	static const size_t N = 8;

	// Constructor(s)
	CharacterMatch()
	: m_Input(array<wchar_t, N>()), m_Output(array<wchar_t, N>()) {}

	CharacterMatch(const wstring& input, const wstring& output)
    : m_Input(toArray<N>(input)), m_Output(toArray<N>(output))
	{
		m_Name = input + L" - " + output;
	}

	// Copy constructor?
    CharacterMatch(const CharacterMatch& that)
    : m_Input(that.m_Input), m_Output(that.m_Output) {}

	// Destructor
	~CharacterMatch();


	// Overloaded = operator
    CharacterMatch& operator=(const CharacterMatch& that)
	{
        m_Input = that.m_Output;
        m_Input = that.m_Output;
        return *this;
    }


	// Accessor functions
	const wchar_t* GetInput() const
	{
        return &m_Input[0];
    }

    const wchar_t* GetOutput() const
	{
        return &m_Output[0];
    }

	const wstring GetName() const
	{
		return m_Name;
	}


private:
	// Members
	wstring m_Name;
	array<wchar_t, N> m_Input;
    array<wchar_t, N> m_Output;

};


#endif // CHARACTER_MATCH_H 


Orthography.h
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#ifndef ORTHOGRAPHY_H
#define ORTHOGRAPHY_H

#define _CRT_SECURE_NO_WARNINGS

//=====================================================
// Includes
//=====================================================
#include "CharacterMatch.h"
#include <vector>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <cstdio>  // for _fileno
#include <io.h>    // for _setmode
#include <fcntl.h> // for _O_U16TEXT


class Orthography
{
public:

	// Constructor(s)
	Orthography();
	Orthography(wchar_t* name);

	// Destructor
	~Orthography();

	// Accessor functions
	wstring GetName() const;
	vector<CharacterMatch> GetCharacterMatches() const;

    // Class functions
	void AddCharacterMatch(const CharacterMatch& match);
	void DeleteCharacterMatch(const wstring& matchName);

	//void LoadOrthographies(vector<Orthography>& orthographies);
	//void SaveOrthographies(vector<Orthography>& orthographies);

private:

	wstring m_Name;
	vector<CharacterMatch> m_CharacterMatches;
	
};


/*
wostream& operator<<(wostream& wos, const Orthography& orth)
{
    wos << orth.from() << L"/" << orth.to();
    return wos;
}

bool parseStr(const wstring& str, Orthography& orth)
{
    size_t pos = str.find(L'/');
    if(pos == str.npos)
        return false;
    wstring f = str.substr(0, pos);
    wstring t = str.substr(pos + 1);
    orth = Orthography(f, t);
    return true;
}

void saveOrthographyToFile(const wstring& filePath, const vector<Orthography>& orthographies)
{
    FILE* fp = _wfopen(filePath.c_str(), L"w,ccs=UNICODE");
    wofstream ofs(fp);

    const size_t count = orthographies.size();
    for(size_t index = 0; count > index; ++index)
        ofs << orthographies[index] << endl;

    fclose(fp);
}

void readOrthographyFromFile(const wstring& filePath, vector<Orthography>& orthographies)
{
    FILE* fp = _wfopen(filePath.c_str(), L"r,ccs=UNICODE");
    wifstream ifs(fp);

    wstring line;
    while(getline(ifs, line)) {
        Orthography orth;
        if(parseStr(line, orth))
            orthographies.push_back(orth);
    }

    fclose(fp);
}

void saveValues(const wstring& filePath)
{
    vector<Orthography> orthographies;
    orthographies.push_back(Orthography(L"a", L"ą"));
    orthographies.push_back(Orthography(L"y", L"ai"));
    orthographies.push_back(Orthography(L"v", L"aw"));
    orthographies.push_back(Orthography(L"f", L"ng"));
    orthographies.push_back(Orthography(L"th", L"þ"));

    wcout << L"Save data to file : c" << filePath << endl;
    saveOrthographyToFile(filePath, orthographies);
    wcout << endl;
}

void readAndDisplayValues(const wstring& filePath)
{
    vector<Orthography> orthographies;

    wcout << L"Read data from file : c" << filePath << endl;
    readOrthographyFromFile(filePath, orthographies);
    wcout << endl;

    ios_base::fmtflags old_flags = wcout.setf(ios_base::left, ios_base::adjustfield);

    wcout << L"Data read:" << endl;
    const size_t count = orthographies.size();
    for(size_t index = 0; count > index; ++index) {
        const Orthography& ortho = orthographies[index];
        wcout << setw(2) << ortho.from << L" -> " << setw(2) << ortho.to << endl;
    }
    wcout << endl;

    wcout.setf(old_flags);
}

int wmain()
{
    _setmode(_fileno(stdout), _O_U16TEXT);

    const wchar_t filePath[] = L"othographies.txt";

    saveValues(filePath);
    readAndDisplayValues(filePath);

    return 0;
}
*/


#endif // ORTHOGRAPHY_H 


Orthography.cpp
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "Orthography.h"

// Constructor
Orthography::Orthography()
{
	
}

Orthography::Orthography(wchar_t* name)
{
	m_Name = name;
}

// Destructor
Orthography::~Orthography()
{

}


// Accessor Functions
wstring Orthography::GetName() const
{
	return m_Name;
}

vector<CharacterMatch> Orthography::GetCharacterMatches() const
{
	return m_CharacterMatches;
}


// Class functions
void Orthography::AddCharacterMatch(const CharacterMatch& match)
{
	m_CharacterMatches.push_back(match);
}

void Orthography::DeleteCharacterMatch(const wstring& matchName)
{
	vector<CharacterMatch>::iterator iter;
	for (iter = m_CharacterMatches.begin(); iter != m_CharacterMatches.end(); iter++)
	{
		if (iter->GetName() == matchName)
		{
			m_CharacterMatches.erase(iter);
		}
	}
}


Note that the m_Name for a CharacterMatch is just the input and output arrays with " - " in the middle. I'd started out trying to cycle through the CharacterMatches to find matching input and outputs to determine which CharacterMatch needs to be deleted but my code ended up pretty unwieldy so I opted to go with a simpler m_Name variable.

All of this works so far except for the CharacterMatch m_Name not being added in this line:
m_CharacterMatches.push_back(match);

Stepping into the program, you see the m_Name under the "match" variable just fine. But once you step past that line and check the m_CharacterMatches to see the CharacterMatch in there, you see the m_Input and m_Output just fine, but the m_Name is set to "" and I have no idea why.

But again, now I am stuck on how to save all of this.
Moving the code around, plus fixing misc issues...

Andy

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// ortho_test
//
// main.cpp

#include <iostream>
#include <iomanip>
#include <cstdio>  // for _fileno
#include <io.h>    // for _setmode
#include <fcntl.h> // for _O_U16TEXT

#include "Orthography.h"

using namespace std;

void saveValues(const wstring& filePath);
void readAndDisplayValues(const wstring& filePath);

int main()
{
    // required to get VC++ runtime to diplay Unicode on
    // console (though chars don't look any different to me...)
    // The chars that turn up in the output file appear ok
    _setmode(_fileno(stdout), _O_U16TEXT);

    const wchar_t filePath[] = L"othographies.txt";

    saveValues(filePath);
    readAndDisplayValues(filePath);

    return 0;
}

void saveValues(const wstring& filePath)
{
    Orthography orth1(L"Viking");
    orth1.AddCharacterMatch(CharacterMatch(L"a", L"ą"));
    orth1.AddCharacterMatch(CharacterMatch(L"y", L"ai"));
    orth1.AddCharacterMatch(CharacterMatch(L"v", L"aw"));
    orth1.AddCharacterMatch(CharacterMatch(L"f", L"ng"));
    orth1.AddCharacterMatch(CharacterMatch(L"th", L"þ"));

    Orthography orth2(L"Alpha");
    orth2.AddCharacterMatch(CharacterMatch(L"a", L"b"));
    orth2.AddCharacterMatch(CharacterMatch(L"e", L"f"));
    orth2.AddCharacterMatch(CharacterMatch(L"i", L"j"));
    orth2.AddCharacterMatch(CharacterMatch(L"o", L"p"));
    orth2.AddCharacterMatch(CharacterMatch(L"u", L"v"));

    Orthography orth3(L"Germanic");
    orth3.AddCharacterMatch(CharacterMatch(L"v", L"f"));
    orth3.AddCharacterMatch(CharacterMatch(L"w", L"v"));
    orth3.AddCharacterMatch(CharacterMatch(L"z", L"s"));

    vector<Orthography> orthographies;
    orthographies.push_back(orth1);
    orthographies.push_back(orth2);
    orthographies.push_back(orth3);

    wcout << L"Save data to file : " << filePath << endl;
    WriteOrthographiesToFile(orthographies, filePath);
    wcout << endl;
}

void readAndDisplayValues(const wstring& filePath)
{
    vector<Orthography> orthographies;

    wcout << L"Read data from file : " << filePath << endl;
    ReadOrthographiesFromFile(orthographies, filePath);
    wcout << endl;

    ios_base::fmtflags old_flags = wcout.setf(ios_base::left, ios_base::adjustfield);

    wcout << L"Data read:" << endl
          << endl;
    const size_t ortho_count = orthographies.size();
    for(size_t ortho_index = 0; ortho_count > ortho_index; ++ortho_index) {
        Orthography& ortho = orthographies[ortho_index];
        wcout << L"Orthography : " << ortho.GetName() << endl;
        vector<CharacterMatch> chmatches = ortho.GetCharacterMatches();
        const size_t chmatch_count = chmatches.size();
        for(size_t chmatch_index = 0; chmatch_count > chmatch_index; ++chmatch_index) {
            CharacterMatch& chmatch = chmatches[chmatch_index];
            wcout << setw(8) << chmatch.GetName() << L" : "
                  << setw(2) << chmatch.GetInput() << L" -> "
                  << setw(2) << chmatch.GetOutput() << endl;
        }
        wcout << endl;
    }
    wcout << endl;

    wcout.setf(old_flags);
}



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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#ifndef CHARACTER_MATCH_H
#define CHARACTER_MATCH_H

//=====================================================
// Includes
//=====================================================
#include <string>
#include <array>
#include <algorithm>
#include <iostream>

template<size_t N, class V>
std::array<wchar_t, N> toArray(const V& v)
{
    std::array<wchar_t, N> d = std::array<wchar_t, N>();
    std::copy(std::begin(v), std::end(v), std::begin(d));
    return d;
}

class CharacterMatch
{
public:
    static const size_t N = 8;

    // Constructor(s)
    CharacterMatch()
    : m_Input(std::array<wchar_t, N>()), m_Output(std::array<wchar_t, N>()) {}

    CharacterMatch(const std::wstring& input, const std::wstring& output)
    : m_Input(toArray<N>(input)), m_Output(toArray<N>(output))
    {
        m_Name = input + L" - " + output;
    }

    // Copy constructor?
    CharacterMatch(const CharacterMatch& that)
    : m_Name(that.m_Name), m_Input(that.m_Input), m_Output(that.m_Output) {}

    // Destructor
    ~CharacterMatch() {}

    // Overloaded = operator
    CharacterMatch& operator=(const CharacterMatch& that)
    {
        m_Name   = that.m_Name;
        m_Input  = that.m_Input;
        m_Output = that.m_Output;
        return *this;
    }

    const std::wstring& GetName() const
    {
        return m_Name;
    }

    // Accessor functions
    const wchar_t* GetInput() const
    {
        return &m_Input[0];
    }

    const wchar_t* GetOutput() const
    {
        return &m_Output[0];
    }

private:
    // Members
    std::wstring m_Name;
    std::array<wchar_t, N> m_Input;
    std::array<wchar_t, N> m_Output;
};

inline std::wostream& operator<<(std::wostream& wos, const CharacterMatch& chmatch)
{
    wos << chmatch.GetInput() << L"/" << chmatch.GetOutput();
    return wos;
}

inline bool parseStr(const std::wstring& str, CharacterMatch& chmatch)
{
    size_t pos = str.find(L'/');
    if(pos == str.npos)
        return false;
    std::wstring input  = str.substr(0, pos);
    std::wstring output = str.substr(pos + 1);
    chmatch = CharacterMatch(input, output);
    return true;
}

#endif // CHARACTER_MATCH_H  

Last edited on
Continued...

Andy

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#ifndef ORTHOGRAPHY_H
#define ORTHOGRAPHY_H

#define _CRT_SECURE_NO_WARNINGS

//=====================================================
// Includes
//=====================================================
#include "CharacterMatch.h"
#include <vector>
#include <iostream>

class Orthography
{
public:
    // Constructor(s)
    Orthography();
    Orthography(const std::wstring& name);

    // Destructor
    ~Orthography();

    // Accessor functions
    const std::wstring& GetName() const;
    std::vector<CharacterMatch> GetCharacterMatches() const;

    // Class functions
    void AddCharacterMatch(const CharacterMatch& match);
    void DeleteCharacterMatch(const std::wstring& matchName);

    // Storage functions
    bool writeToStream(std::wostream& wos) const;
    bool readFromStream(std::wistream& wis);

private:
    std::wstring m_Name;
    std::vector<CharacterMatch> m_CharacterMatches;
};

void WriteOrthographiesToFile(const std::vector<Orthography>& orthographies, const std::wstring& filepath);
void ReadOrthographiesFromFile(std::vector<Orthography>& orthographies, const std::wstring& filepath);

#endif // ORTHOGRAPHY_H  



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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "Orthography.h"
#include <fstream>
using namespace std;

const wchar_t orthoBegin[] = L"BEGIN ORTHOGRAPHY:";
const wchar_t orthoEnd  [] = L"END ORTHOGRAPHY";

// Constructor
Orthography::Orthography()
{
}

Orthography::Orthography(const wstring& name) : m_Name(name)
{
}

// Destructor
Orthography::~Orthography()
{
}

// Accessor Functions
const wstring& Orthography::GetName() const
{
	return m_Name;
}

vector<CharacterMatch> Orthography::GetCharacterMatches() const
{
	return m_CharacterMatches;
}

// Class functions
void Orthography::AddCharacterMatch(const CharacterMatch& match)
{
	m_CharacterMatches.push_back(match);
}

void Orthography::DeleteCharacterMatch(const wstring& matchName)
{
	vector<CharacterMatch>::iterator iter;
	for (iter = m_CharacterMatches.begin(); iter != m_CharacterMatches.end(); iter++)
	{
		if (iter->GetName() == matchName)
		{
			m_CharacterMatches.erase(iter);
		}
	}
}

bool Orthography::writeToStream(std::wostream& wos) const
{
	bool ret_val = true;
	wos << orthoBegin << m_Name << endl;
	// from saveOrthographyToFile
	const size_t count = m_CharacterMatches.size();
	for(size_t index = 0; count > index; ++index)
		wos << m_CharacterMatches[index] << endl;
	// end
	wos << orthoEnd << endl;
	return ret_val;
}

bool Orthography::readFromStream(std::wistream& wis)
{
	bool ret_val = true;
	bool got_end = false;
	{
		wstring line;
		getline(wis, line);
		if(0 == line.find(orthoBegin))
			m_Name = line.substr(wcslen(orthoBegin));
		else
			ret_val = false;
	}
	if(ret_val)
	{
		// based on readOrthographyFromFile
		wstring line;
		while(getline(wis, line)) {
			if(line == orthoEnd) {
				got_end = true;
				break;
			}
			CharacterMatch chmatch;
			ret_val = parseStr(line, chmatch);
			if(!ret_val)
				break;
			m_CharacterMatches.push_back(chmatch);
		}
	}
	if(ret_val) {
		ret_val = got_end;
	}
	return ret_val;
}

void ReadOrthographiesFromFile(vector<Orthography>& orthographies, const wstring& filePath)
{
	FILE* fp = _wfopen(filePath.c_str(), L"r,ccs=UNICODE");
	wifstream ifs(fp);

	for( ; ; )
	{
		Orthography orth;
		if(!orth.readFromStream(ifs))
			break;
		orthographies.push_back(orth);
	}

	fclose(fp);
}

void WriteOrthographiesToFile(const vector<Orthography>& orthographies, const wstring& filePath)
{
	FILE* fp = _wfopen(filePath.c_str(), L"w,ccs=UNICODE");
	wofstream ofs(fp);

	const size_t count = orthographies.size();
	for(size_t index = 0; count > index; ++index)
	{
		const Orthography& orth = orthographies[index];
		orth.writeToStream(ofs);
	}

	fclose(fp);
}
Last edited on
The saved date files looks like this (in Unicode)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
BEGIN ORTHOGRAPHY:Viking
a/ą
y/ai
v/aw
f/ng
th/þ
END ORTHOGRAPHY
BEGIN ORTHOGRAPHY:Alpha
a/b
e/f
i/j
o/p
u/v
END ORTHOGRAPHY
BEGIN ORTHOGRAPHY:Germanic
v/f
w/v
z/s
END ORTHOGRAPHY


It will be easy enough to modify the code to save the name as well. You just need to tweak operator<< and parseStr to do so.

But if the name is always of the form "a - e" then I prob would remove m_Name from class CharacterMatch and alter GetName to

1
2
3
4
5
6
7
    std::wstring GetName() const
    {
        std::wstring name = &m_Input[0];
        name += L" - ";
        name += &m_Output[0];
        return name;
    }


Andy
Last edited on
Wow! I've started going through the code and will be able to give it more attention tomorrow. Quick question though. You have some matches hard-coded into the savevalues function. Would that be a way to set up some pre-made orthographies or were you just doing to as a way to plug in some information to show how it works?
Out of interest, do you use a diff tool?

The one I currently prefer is DiffMerge, which is free.
http://www.sourcegear.com/diffmerge/

(and I see there's a new version for me to download!)

Andy

diff
http://en.wikipedia.org/wiki/Diff
No, I sure don't. Didn't know what one was until you pointed it out.

I am having a couple issues with your code though.

I get a red line under the equal sign on this line:

m_Name = line.substr(wcslen(orthoBegin));

When I hover over it it says "no "=" matches these operands".

Is it because m_Name is a wstring and orthoBegin is a const wchar_t? Does it need to be converted?

I also get this error when I try to compile:

1
2
3
4
5
orthography.cpp(113): error C2663: 'std::vector<_Ty>::push_back' : 2 overloads have no legal conversion for 'this' pointer
1>          with
1>          [
1>              _Ty=CharacterMatch
1>          ]


Line 113 is:

m_CharacterMatches.push_back(chmatch);

I get a red line under the period in that light. Hovering over it says "no instance of overloaded function..." and a whole bunch of other stuff.

I took your suggested and changed the GetName() function for CharacterMatches. That was pretty much what I was trying to do last night but was going about it in an incredibly round-about way. I'd probably been staring at the code for too long and couldn't see the simpler, easier way that was right in front of my face.

I've also made it to where the user can't add a match if the exact one already exists. I've also made it to where the user can't add an orthography if they are trying to make a new one with the same name as an existing one.

Basically that just means I am fine-tuning some things that I am able to while we hammer this out. And I want to say again how much I appreciate your time with this :).

Also, what would be your recommendation for loading the saved orthographies into the program? As they are selected in the combo box (which means at least the titles of them would need to be loaded) or load them all when the program starts? It isn't like I expect 72649028405 orthographies to be added by someone. Maybe a handful or so.

Oh, before I forget, I'd like to ask about the "std::" you are using. Is it recommended to go that route rather than just using "using namespace std;"? Is it just a good practice to follow?
Is it because m_Name is a wstring and orthoBegin is a const wchar_t? Does it need to be converted?

1. orthoBegin is not a wchar_t, it's a t wchar_t array
2. orthoBegin is passed to wcslen, which is what would complaining if the type was wrong
3. wcslen returns a size_t (which is an unsigned int or similar)
4. which is fed to substr, which returns the same sort of string as line is

What is wrong is either:
a. m_Name or line is the wrong sort of string (string versus wstring)
b. or the method is const (so m_Name cannot be set)

No conversion should be necessary.

Hovering over it says "no instance of overloaded function..."

I have no idea about this.

Check that the method isn't const or something.

(The code I posted compiles cleanly with Visual C++ 2010, which is what I thought you were using?)

As they are selected in the combo box ... or load them all when the program starts?

I would prob load them at program start and save them (if changed) when the program exits. But that would be easy enough to change later.

Is it recommended to go that route rather than just using "using namespace std;"?

Yes.

I see using namespace std; as very much a beginner's habit. But you'll see I only made that change in the headers. That's because it's seen to be a very bad practice to use "using namespace std;" in a header, because it spreads the namespace all over the place.

But it's more or less ok to use in a .cpp file after the headers have been included.

Andy
Last edited on
Your const mention was right on the money. This line:

bool readFromStream(std::wistream& wis);

I put as:

bool readFromStream(std::wistream& wis) const;

I retyped your code (a habit I picked up to try to help myself learn rather than just copy/pasting) and made a mistake :). And that fixed both of the problems I mentioned earlier.

I got the saveValues function to work and save to a file (I attached that function to a button on my form). Now I am going to work on getting the read function to read from the file and display it in the list box on the form. Then I'm going to see about getting a custom orthography entered by the user to save to the file in the place of the hard-coded examples you used. I'm feeling optimistic about this and I'll be plugging away at it :).
Just a quick update. It would appear that I got the saving to and reading from a file working and it feeds into my program beautifully :). I had a few issues but after the most in-depth "stepping into" I've ever done (took days!), I managed to find the problem (turns out I retyped a small portion of your code wrong hehe). I have another issue but it is different and will be in another post.

Just wanted to say thank you!
Topic archived. No new replies allowed.
Pages: 12