RPG File i/o question

Pages: 12
I never code return EXIT_FAILURE;, lol. I just used that so I didn't have to comment :P

You can just change that to: return 1;

As for the output, can you paste it here so I can see it?

If you need an explanation for any of the code, just ask away!
SSword
Short Sword
common
2
4
copper
5




-2
1967665575

4205032


Process returned 0 (0x0)   execution time : 0.106 s
Press any key to continue.


Thanks again. I think I'll keep the return EXIT_FAILURE;. It seems the program is returning something from a random address. But I swear it is always the same values.
I just discovered something! I thought the problem might be the txt file itself...
So I added another item to read/cout. The garbage is no longer there. i think it has something to do with the iterating through one of the functions.

SSword
Short Sword
common
2
4
copper
5

LSword
Long Sword
common
4
7
copper
10


Process returned 0 (0x0)   execution time : 0.120 s
Press any key to continue.

I put this in and it seems to crash after less than a second.
// Ignore lines with // proceeding them
// Weapons will have the following format:
// Item Description Rarity Min_Damage Max_Damage Value(in copper silver or gold)
// Example:
// SSword Short_Sword common 2 4 copper 5
// LSword Long_Sword common 4 7 copper 10
// SciSword Scimitar uncommon 25 35 silver 2
// DragSword Dragon_Sword" rare 150 200 gold 125
// Excal1 Excalibur legand 1000 1300 gold 10000
SSword Short_Sword common 2 4 copper 5
LSword Long_Sword common 4 7 copper 10
SciSword Scimitar uncommon 25 35 silver 2

Then I put this in and it crashes instantaneously.
// Ignore lines with // proceeding them
// Weapons will have the following format:
// Item Description Rarity Min_Damage Max_Damage Value(in copper silver or gold)
// Example:
// SSword Short_Sword common 2 4 copper 5
// LSword Long_Sword common 4 7 copper 10
// SciSword Scimitar uncommon 25 35 silver 2
// DragSword Dragon_Sword" rare 150 200 gold 125
// Excal1 Excalibur legand 1000 1300 gold 10000
SSword Short_Sword common 2 4 copper 5
LSword Long_Sword common 4 7 copper 10
SciSword Scimitar uncommon 25 35 silver 2
DragSword Dragon_Sword" rare 150 200 gold 125

EDIT:
I forgot to change the constant...Why do I need to have the const int wMAX = 5; in the code. I will be modding the list of items heavily. I would hate to have to recompile each time I add a new item. Modding is the reason I made this list. Someday I am going to make myself a moddable game to tinker with and improve(both code and game). Is there a way to take this variable out?
Last edited on
I think return EXIT_FAILURE; just returns a non-zero value.

If I ever need to use a loop to output an array, I always use a const int to create the array and use the same const int in the loop. That way I don't have to go all through my code changing stuff.

You could create, say, a const int of 200 and fill up only 100 of them. Then do something like the following to output them:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
	for( int i = 0; i < wMAX; ++i )
	{
		// if the indexed weapon.item is empty
		// there were not that many weapons to load from file
		// so break from the for-loop
		if( wList[ i ].item.empty() )
			break;

		std::cout << "Item:\t\t" << wList[ i ].item << '\n';
		std::cout << "Description:\t" << wList[ i ].description << '\n';
		std::cout << "Rarity:\t\t" << wList[ i ].rarity << '\n';
		std::cout << "Min Damage:\t" << wList[ i ].MIN_DMG << '\n';
		std::cout << "Max Damage:\t" << wList[ i ].MAX_DMG << '\n';
		std::cout << "Coin type:\t" << wList[ i ].coinType << '\n';
		std::cout << "Coim amount:\t" << wList[ i ].coinAmount << '\n' << '\n';
	}

But this way, you'd have 100 weapon-structs uninitialised.

You could create them by using the new keyword.
This way, you'll allocate memory for the weapon when needed.

If you don't know about new, maybe code it with room to spare, i.e.
1
2
const int wMAX = 200;
weapons[ wMAX ];

And then adapt your code when you learn more.


Also, I just realised. The above code, when I pasted it earlier, I never entered the description of each cout, ahaha!
Thanks for the help and ideas. I have tried to put the stuff you had in main into load.cpp and includes.h. I am getting all kind of funky errors. Then I attempted to fix some things. Now I am left with a new error. this covers a new part of c++ I do not yet fully grasp.

1
2
3
4
5
6
7
8
9
10
//main.cpp
#include "includes.h"

using namespace std;

int main()
{
    ShowItems(10);
    return 0;
}


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
//includes.cpp
#define INCLUDES_H

#include <iostream>
#include <sstream>
#include <fstream>
#include "load.cpp"

struct weapons
{
    std::string item;
    std::string description;
    std::string rarity;
    int MIN_DMG;
    int MAX_DMG;
    std::string coinType;
    int coinAmount;
};

// function prototypes
bool load( weapons w[] );



#endif // INCLUDES_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
//load.cpp
#include "includes.h"

bool load( weapons w[] )
{
	// ifstream defaults to std::ios::in, but I use it there anyway
	std::ifstream iFile( "Weapons.txt", std::ios::in );

	// if the file is NOT open
	if( ! iFile.is_open() )
	{
		std::cout << "Unable to open file...\n";

		// return, file error
		return false;
	}

	std::string input;
	std::stringstream ss;

	int index = 0;

	// while it's NOT the end of the file
	while( ! iFile.eof() )
	{
		std::getline( iFile, input, ' ' );

		//
		// check to see if the line has a comment
		//
		if( input.substr( 0, 1 ) == "/" )
		{
			// if the current line has a "/" at the start
			// get the whole line and restart the loop
            std::getline( iFile, input, '\n' );
			continue;
		}

		// set the item name
		w[ index ].item = input;

		// get description
		std::getline( iFile, input, ' ' );
		w[ index ].description = input;

		// remove the underscores from the description
		for( unsigned int i = 0; i < w[ index ].description.size(); ++i )
		{
			// if un underscore is found, at the same element in the string,
			// set it to a space ' '
			if( w[ index ].description[ i ] == '_' )
				w[ index ].description[ i ] = ' ';
		}

		// get rarity
		std::getline( iFile, input, ' ' );
		w[ index ].rarity = input;

		// get minimum damage
		std::getline( iFile, input, ' ' );

		// clear, add input to ss, stream to int
		ss.clear();
		ss << input;
		ss >> w[ index ].MIN_DMG;

		// get max damage
		std::getline( iFile, input, ' ' );

		// clear, add input to ss, stream to int
		ss.clear();
		ss << input;
		ss >> w[ index ].MAX_DMG;

		// get coin type
		std::getline( iFile, input, ' ' );
		w[ index ].coinType = input;

		// get coin amount. Last variable, line end( '\n' )
		std::getline( iFile, input, '\n' );

		ss.clear();
		ss << input;
		ss >> w[ index ].coinAmount;

		// move to the next index
		++index;
		ss.clear();
	}
	// exit after the file has finished being read
	return true;
}

int ShowItems(int MaxNumber)
{
    while(true)
    {
    // max weapons
    const int wMAX = 50;

    weapons wList[ wMAX ];

    // if the load fails, exit program
    if( ! load( wList ) )
        return 1;

    for( int i = 0; i < wMAX; ++i )
    {
        // if the indexed weapon.item is empty
        // there were not that many weapons to load from file
        // so break from the for-loop
        if( wList[ i ].item.empty() )
            break;

        std::cout << "Item:\t\t" << wList[ i ].item << '\n';
        std::cout << "Description:\t" << wList[ i ].description << '\n';
        std::cout << "Rarity:\t\t" << wList[ i ].rarity << '\n';
        std::cout << "Min Damage:\t" << wList[ i ].MIN_DMG << '\n';
        std::cout << "Max Damage:\t" << wList[ i ].MAX_DMG << '\n';
        std::cout << "Coin type:\t" << wList[ i ].coinType << '\n';
        std::cout << "Coim amount:\t" << wList[ i ].coinAmount << '\n' << '\n';
    }
    break;
    }
    return 0;
}


This is the error I am getting:
F:\CodeBlocks-Programs\LittleRPG\load.cpp|3|error: 'weapons' was not declared in this scope|
F:\CodeBlocks-Programs\LittleRPG\load.cpp|4|error: expected ',' or ';' before '{' token|
||=== Build finished: 2 errors, 0 warnings (0 minutes, 1 seconds) ===|
Don't know if it makes any difference, but the includes file should be .h not .cpp. This could be the cause of the errors, as you haven't defined the file, or you're including a .h file extension and you're actually using a .cpp file extension.

Also, the includes file;
1
2
3
4
5
6
#ifndef INCLUDES_H
#define INCLUDES_H

// stuff

#endif 


Again, in the includes file. You have no prototype for the ShowItems() function. Plus, this could be a void function, as you're doing nothing with the return value.

Also, you pass MaxNumber to the ShowItems() function, but never use it.
I fixed the problems. How do I bring the weapons into scope? And the .cpp was actually a .h file. I prototyped ShowItems(), fixed the MaxNumber issue, and the void. I still get the same error, though. As I don't understand the weapons w[] thing, I have no idea what to do about it. Did I forget something?
Ok, I just copy and pasted all your code in to my VS and changed things to what you've changed too. I took out line 7 of your includes file; #include "load.cpp" , you shouldn't have to use that. Not in VS, anyway.

I can't see where this error is coming from. Does your compiler tell you at which line this error is from?

By creating a struct, you are creating a type. i.e char, int, string.

So when you pass to functions you pass with a type of 'weapons' and then the name, in this case 'w[]'.
'[]' because it's an array of weapons.
I changed int ShowItems(int MaxNumber) from void to int return. The include in the .h was causing a big part of the problem. I get a compiler warning now:
F:\CodeBlocks-Programs\LittleRPG\load.cpp||In function 'int ShowItems(int)':|
F:\CodeBlocks-Programs\LittleRPG\load.cpp|100|warning: ISO C++ forbids variable length array 'wList' [-Wvla]|
||=== Build finished: 0 errors, 1 warnings (0 minutes, 4 seconds) ===|

But it works again. Thanks.
P.S. could you explain why ISO forbids variable length array 'wList'? Thanks again for your help. :o)
Arrays need to be created with a constant size. If you need some non-constant value to be used for the size, use a std::vector (or dynamically allocate the memory your self with new/delete, but I don't recommend it).
You can keep it as a void and still return; if the load fails, if that's why you changed it back.

And as ModShop said, it needs to be a constant size. That's why I create a const int, so that I can create an array and also use the const int variable within loops etc, to avoid access violations( out of bounds ) errors with the array.
Thank you ModShop.
I have created a switch statement to determine rarity of an item. I really don't want to use if statements. how can I make this work?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int rvalue = 0;//rarity value to add to rarity
    switch(mindmg)
    {
    case >99:
    case <251:
        rvalue =+ 100;
        break;
    case >250:
    case <1001:
        rvalue =+ 250;
        break;
    case >1000:
    case <3001:
        rvalue =+ 750;
        break;
    case >5000:
        rvalue =+ 1250;
        break;
    default:
        rvalue =+ 0;
        break;
    }


EDIT:
I just realized how the question sounded. I was a little miffed that the switch statement didn't work. i figured it wouldn't, but I crossed my fingers and tried anyway. I was trying to avoid using if statements but it looks like I am going to have to. Is switch really so limited that I cannot use an expression in the case?
Last edited on
I decided to use if statements. I have a new question...
This is a member function:
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
string Item::setprefix()
{
    std::ifstream iFile("Weapons.txt");
    if( ! iFile.is_open() )
	{
		std::cout << "Unable to open file...\n";

		// return, file error
		return "Error::setprefix()::WeaponPrefix.txt!";
	}
	std::string input;
	int index = 0;
	// while it's NOT the end of the file
	while( ! iFile.eof() )
	{
		std::getline( iFile, input);

		//
		// check to see if the line has a comment
		//
		if( input.substr( 0, 1 ) == "/" )
		{
			// if the current line has a "/" at the start
			// get the whole line and restart the loop
            std::getline( iFile, input, '\n' );
			continue;
		}

        vector<string> prefix;

		// get prefix
		std::getline( iFile, input, '\n' );
		prefix.push_back(input);

		// remove the underscores from the description
		for( unsigned int i = 0; i < prefix.size(); ++i )
		{
			// if un underscore is found, at the same element in the string,
			// set it to a space ' '
			if( prefix[ i ] == '_' )
				prefix[ i ] = ' ';
		}

        // move to the next index
		++index;
	}
	// exit after the file has finished being read
    return "prefix";
}

I adapted it from something Lynx876 helped me with. However, I get this error:
E:\CodeBlocks-Programs\CreateItemsTXT\main.cpp||In member function 'std::string Item::setprefix()':|
E:\CodeBlocks-Programs\CreateItemsTXT\main.cpp|222|error: no match for 'operator==' in 'prefix.std::vector<_Tp, _Alloc>::operator[] [with _Tp = std::basic_string<char>, _Alloc = std::allocator<std::basic_string<char> >, std::vector<_Tp, _Alloc>::reference = std::basic_string<char>&, std::vector<_Tp, _Alloc>::size_type = unsigned int](i) == '_''|
E:\CodeBlocks-Programs\CreateItemsTXT\main.cpp|222|note: candidates are:|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\postypes.h|218|note: template<class _StateT> bool std::operator==(const std::fpos<_StateT>&, const std::fpos<_StateT>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\stl_pair.h|201|note: template<class _T1, class _T2> bool std::operator==(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\stl_iterator.h|285|note: template<class _Iterator> bool std::operator==(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\stl_iterator.h|335|note: template<class _IteratorL, class _IteratorR> bool std::operator==(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\allocator.h|122|note: template<class _T1, class _T2> bool std::operator==(const std::allocator<_T1>&, const std::allocator<_T2>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\allocator.h|127|note: template<class _Tp> bool std::operator==(const std::allocator<_Tp1>&, const std::allocator<_Tp1>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\basic_string.h|2427|note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\basic_string.h|2434|note: template<class _CharT> typename __gnu_cxx::__enable_if<std::__is_char<_Tp>::__value, bool>::__type std::operator==(const std::basic_string<_CharT>&, const std::basic_string<_CharT>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\basic_string.h|2448|note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\basic_string.h|2460|note: template<class _CharT, class _Traits, class _Alloc> bool std::operator==(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\streambuf_iterator.h|194|note: template<class _CharT, class _Traits> bool std::operator==(const std::istreambuf_iterator<_CharT, _Traits>&, const std::istreambuf_iterator<_CharT, _Traits>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\stl_vector.h|1273|note: template<class _Tp, class _Alloc> bool std::operator==(const std::vector<_Tp, _Alloc>&, const std::vector<_Tp, _Alloc>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\ext\new_allocator.h|123|note: template<class _Tp> bool __gnu_cxx::operator==(const __gnu_cxx::new_allocator<_Tp>&, const __gnu_cxx::new_allocator<_Tp>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\stl_iterator.h|805|note: template<class _Iterator, class _Container> bool __gnu_cxx::operator==(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)|
e:\programs\codeblocks-ep\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\bits\stl_iterator.h|799|note: template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator==(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)|
||=== Build finished: 17 errors, 0 warnings (0 minutes, 2 seconds) ===|
I want the same functionality, but, it will just be a simp0le list of words or two or even three words that will go into the vector as one piece of information. I don't know why I am getting the error.
Last edited on
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
	// create this outside of the loop
	// each time you push_back( input ) it will add
	// an element to the vector
	std::vector< std::string > prefix;

	// while it's NOT the end of the file
	while( ! iFile.eof() )
	{
		std::getline( iFile, input);

		//
		// check to see if the line has a comment
		//
		if( input.substr( 0, 1 ) == "/" )
		{
			// if the current line has a "/" at the start
			// get the whole line and restart the loop
            std::getline( iFile, input, '\n' );
			continue;
		}

		// get prefix
		std::getline( iFile, input, '\n' );

		// remove the underscores from the description
		for( unsigned int i = 0; i < input.size(); ++i ) // input, not prefix.size()
		{
			// if un underscore is found, at the same element in the string,
			// set it to a space ' '
			if( input[ i ] == '_' ) // here, you need to change input, not
				input[ i ] = ' ';   // the vector
		}

		prefix.push_back(input); // then add it in to the vector after removing underscores
	}


EDIT:
I actually wrote code for this. I created a vector to hold a struct, which has the variables for file/user input.

EDIT 2:
This is actually for getting user input, to later, save to a file. But the concept is the same for file input, without all the checks etc.

Here's a bit of the code:
includes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// weapon struct
struct weapons
{
	int ID;
	std::string item;
	std::string description;
	int power;
	int cost;
};


// typedef, for a weapon vector
// saves typing 'std::vector< weapons >'
// to create a vector. Now you can just type 'vWep'
typedef std::vector< weapons > vWep;


inputValues.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
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
#include "includes.h"

void inputValues( vWep &vecW )
{
	// create a weapons struct
	weapons weps;

	// create a stringstream object
	std::stringstream ss;

	std::string input;

	std::cout << "Enter values; ENTER to exit;\n";

	while( true )
	{
		// print message, get a line from the console, up
		// until the '\n'( NEWLINE ) character is reached
		std::cout << "\nItem >\t";
		std::getline( std::cin, input, '\n' );

		// if the user presses enter without entering anything
		// break from the while-loop
		if( input == "" )
			break;

		// if the input string does NOT matche a pre-defined item
		// print error, re-start loop. Also converts to upper case
		if( ! itemCheck( input ) )
		{
			std::cout << "Undefined item error.\n";
			continue;
		}

		// weapons-struct.item equals users input
		weps.item = input;


		std::cout << "Desc >\t";
		std::getline( std::cin, input, '\n' );

		if( input == "" )
			break;

		// check for a duplicate decription within the vector
		if( duplicate( vecW, input ) )
		{
			std::cout << "\n\nDuplicate entry\n\n";
			continue;
		}

		weps.description = input;


		std::cout << "Pwer >\t";
		std::getline( std::cin, input, '\n' );

		if( input == "" )
			break;

		// pass the stringstream 'input'
		ss << input;

		// stream the int in to weapon-struct.power
		ss >> weps.power;

		// clear the stringstream object
		ss.clear();


		std::cout << "Cost >\t";
		std::getline( std::cin, input, '\n' );

		if( input == "" )
			break;

		ss << input;
		ss >> weps.cost;
		ss.clear();

		// get the vector size and use that for the weapon ID
		weps.ID = vecW.size();

		// add the newly created weapon-struct to the vector
		vecW.push_back( weps );
	}
}
Last edited on
Sorry for the long time between replies. I had to get a second job and not had time to do much else. Anyway. I adapted my code with your ideas. On first glance it worked perfectly. The problem is that my test output is a little strange, and kind of ADHD like yours truly...
shattering
curdling
low
slicing
destroyer
terrible

Process returned 0 (0x0)   execution time : 0.527 s
Press any key to continue.

I know I know. you may ask what is so strange about this. Here is the file it is reading from...
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
/prefix
spider
monkey
shattering
smashing
curdling
high
low
double edged
slicing
cutting
destroyer
abominable
terrible
dark
light
heavy
puny
tiny
toy
kings
emporers
queens
druid
flimsy
fluid
bright
jagged
jaguar
wolf
timber
phantom
menacing
forsaken
gifted
deadly
gladius
crafted
shreiking
screaming

It took me a minute to ralize that it is not, in fact, reading the first through sixth items.
Here is my code:
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
//main.cpp
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <stdlib.h>
#include <time.h>

using namespace std;


int random(int first, int last)
{
    return rand() % last + first;
}

struct Item
{
    string item;
    string description;
    enum rarity_type {common = 1, uncommon, rare, legend};
    rarity_type rarity;
    int mindmg;
    int maxdmg;
    enum coin_type {copper = 1, silver, gold};
    coin_type coin;
    int value;
    void check_value();
    void save();
    void init();
    void check_rarity();
    string setprefix();
    string setsuffex();
    string settype();
    int setmindmg();
    int setmaxdmg();
};

int main()
{
    Item item;
    item.setprefix();
    return 0;
}

void Item::check_value()
{
    value = ((mindmg)+(maxdmg))*(rarity+1);
}

void Item::save()
{
    ofstream file("StockWeapons.txt",ios::app);
    string rrty;//temp rarity
    switch(rarity)
    {
    case 1:
        rrty = "common";
        break;
    case 2:
        rrty = "uncommon";
        break;
    case 3:
        rrty = "rare";
        break;
    case 4:
        rrty = "legend";
        break;
    default:
        rrty = "common_error";
        break;
    }
    string cn;//temp coin type
    switch(coin)
    {
    case 1:
        cn = "copper";
        break;
    case 2:
        cn = "silver";
        break;
    case 3:
        cn = "gold";
        break;
    default:
        cn = "copper_error";
        break;
    }
    file << item << " " << description << " " << rrty;
    file << " " << mindmg << " " << maxdmg << " ";
    file << cn << " " << value << endl;
    file.close();
}

void Item::init()
{
    //get a name and weapon type then combine for item
    srand ( time(NULL) );
    //random(int x, int y);
}

void Item::check_rarity()
{
    int rvalue = 0;//rarity value to add to rarity
    while(true)
    {
        if(mindmg > 99 && mindmg < 251)
        {
            rvalue =+ 100;
            break;
        }
        if(mindmg  > 250 && mindmg < 1001)
        {
            rvalue =+ 250;
            break;
        }
        if(mindmg > 1000 && mindmg < 3001)
        {
            rvalue =+ 750;
            break;
        }
        if(mindmg > 5000)
        {
            rvalue =+ 1250;
            break;
        }
    }
    while(true)
    {
        if(maxdmg > 139)
        {
            rvalue =+ 100;
            break;
        }
        if(maxdmg > 275)
        {
            rvalue =+ 250;
            break;
        }
        if(maxdmg > 1250)
        {
            rvalue =+ 750;
            break;
        }
        if(maxdmg > 6000)
        {
            rvalue =+ 1250;
            break;
        }
    }
    int rndm = 0;
    while(true)
    {
        if(rvalue > 2499)
            rndm = 4;
        if(rvalue > 1499)
            rndm = 3;
        if(rvalue > 499)
            rndm = 2;
        if(rvalue > 199)
            rndm = 1;
        break;
    }
    srand ( time(NULL) );
    rndm = random(1 + rndm, 9);
    rarity_type r = common;//temp rarity
    switch(rndm)
    {
    case 9:
        r = legend;
        break;
    case 8:
        r = rare;
        break;
    case 7:
        r = uncommon;
        break;
    default:
        r = common;
        break;
    }
    rarity = r;
}

string Item::setprefix()
{
    std::ifstream iFile("WeaponPrefix.txt");
    if( ! iFile.is_open() )
    {
        std::cout << "Unable to open file...\n";

        // return, file error
        return "Error::setprefix()::WeaponPrefix.txt!";
    }	// create this outside of the loop
    // each time you push_back( input ) it will add
    // an element to the vector
    std::vector< std::string > prefix;
    std::string input;

    // while it's NOT the end of the file
    while( ! iFile.eof() )
    {
        std::getline( iFile, input);

        //
        // check to see if the line has a comment
        //
        if( input.substr( 0, 1 ) == "/" )
        {
            // if the current line has a "/" at the start
            // get the whole line and restart the loop
            std::getline( iFile, input, '\n' );
            continue;
        }

        // get prefix
        std::getline( iFile, input, '\n' );

        // remove the underscores from the description
        for( unsigned int i = 0; i < input.size(); ++i ) // input, not prefix.size()
        {
            // if un underscore is found, at the same element in the string,
            // set it to a space ' '
            if( input[ i ] == '_' ) // here, you need to change input, not
                input[ i ] = ' ';   // the vector
        }

        prefix.push_back(input); // then add it in to the vector after removing underscores
    }
    cout << prefix[0] << endl;
    cout << prefix[1] << endl;
    cout << prefix[2] << endl;
    cout << prefix[3] << endl;
    cout << prefix[4] << endl;
    cout << prefix[5] << endl;
    // exit after the file has finished being read
    return "prefix";
}

string Item::setsuffex()
{
    return "suffex";
}
string Item::settype()
{
    return "type";
}
int Item::setmindmg()
{
    return 1;
}
int Item::setmaxdmg()
{
    return 2;
}

Please bare in mind that it is just a little test code on lines 230-235 that show the problem. I am wondering why it is doing this. Could it be a problem with a loop?
Last edited on
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
string Item::setprefix()
{
    std::ifstream iFile("WeaponPrefix.txt");
    if( ! iFile.is_open() )
    {
        std::cout << "Unable to open file...\n";

        // return, file error
        return "Error::setprefix()::WeaponPrefix.txt!";
    }	// create this outside of the loop
    // each time you push_back( input ) it will add
    // an element to the vector
    std::vector< std::string > prefix;
    std::string input;

    // while it's NOT the end of the file
    while( ! iFile.eof() )
    {
        std::getline( iFile, input);

        //
        // check to see if the line has a comment
        //
        if( input.substr( 0, 1 ) == "/" )
        {
            // if the current line has a "/" at the start
            // get the whole line and restart the loop
            //std::getline( iFile, input, '\n' );	// [1] READ NOTES BELOW!
            continue;
        }

        // get prefix
        //std::getline( iFile, input, '\n' );	// [2] READ NOTES BELOW!

        // remove the underscores from the description	// [3] READ NOTES BELOW!
        for( unsigned int i = 0; i < input.size(); ++i ) // input, not prefix.size()
        {
            // if un underscore is found, at the same element in the string,
            // set it to a space ' '
            if( input[ i ] == '_' ) // here, you need to change input, not
                input[ i ] = ' ';   // the vector
        }

        prefix.push_back(input); // then add it in to the vector after removing underscores
    }

	// print the whole vector
	for( unsigned int i = 0; i < prefix.size(); ++i )
		cout << prefix[ i ] << '\n';
	
    // exit after the file has finished being read
    return "prefix";
}



[1]NOT needed, as the getline above, line 19, will get the next line when the program reads continue;.

[2]Using this getline will overwrite the current line before adding to the vector!

[3]Do you really need this now? You have no underscores within the text file. This will just slow your program.( not really noticeable ).
Topic archived. No new replies allowed.
Pages: 12