Issues with Writing to Text File

I'm working on a map program. I want the user to enter values for a coordinate and they be saved on a text file. The strings that they type in are entered fine onto array, but the integers aren't. Whenever I try to put an integer into it they come out as symbols or nothing.

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
string markName = "";
    string type = "";
    unsigned int coordX;
    unsigned int coordY;
    int incrementer = 0;
    int inCounter = 0;
    string marks[400];


int fCounter = 0;
int fileO(int coordX, int coordY, string markName, string type, string marks[400], int incrementer)
{
    ifstream inFile; // Declare inFile
    ofstream outFile; // Declare outFile

    if (!inFile.is_open())  //Check to see if file is open
    {
        outFile.open("coordFile.txt", ios::out | ios::app); //If not, open file for output
    }
    else { //If the file was opened...
        inFile.close(); //Close it
    }



    marks[fCounter] = markName;
    outFile << marks[fCounter] << " - ";
    fCounter++;
    marks[fCounter] = type;
    outFile << marks[fCounter] << endl;
    fCounter++;
    marks[fCounter] = coordX;
    outFile << marks[fCounter] << ", ";
    fCounter++;
    marks[fCounter] = coordY;
    outFile << marks[fCounter];
    fCounter++;


}


//ENTER VALUES! This is in SFML, so this is a fraction of the event loop.
if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::A))
            {
                cout << "Please name the mark: ";
                getline(cin,markName);
                cout << "Please define the mark: ";
                getline(cin,type);
                cout << "Please enter the X coordinate: ";
                cin >> coordX;
                cout << "Please enter the Y coordinate: ";
                cin >> coordY;
                cin.ignore();
                fileO(coordX,coordY,markName,type,marks,incrementer);

                inCounter++;
            }
You must pay better attention to the type of things. Take line 32 for example:

  marks[fCounter] = coordX;

The types of the things you are manipulating are:

  string = unsigned int

...which does not do what you think it does. (You should be getting a compile error.)


You should be aware, also, that you are not making good use of your 'marks' array -- its values are not homogenous. If a mark needs to contain the following information:

  · string 'name'
  · string 'type' (whatever that is)
  · unsigned 'x coordinate'
  · unsigned 'y coordinate'

then you should put them in a structure:

1
2
3
4
5
6
7
struct mark_t
  {
  string name;
  string type;
  unsigned x;
  unsigned y;
  };

and then a list of marks is:

1
2
// A list of, at max, 400 marks
mark_t marks[ 400 ];

I recommend you use a deque or vector instead of a simple array. They have many advantages.

1
2
#include <deque>
deque <mark_t> marks;


In any case, you then need to make your routine properly handle a mark. You can create a constructor for your mark:

1
2
3
4
5
6
7
struct mark_t
  {
  ...
  mark_t( unsigned x, unsigned y, const string& name, const string& type ):
    name( name ), type( type ), x( x ), y( y )
    { }
  };

Adding a mark to the 'array' is then simple:

53
54
    cin >> coordY;
    marks.push_back( mark_t( coordX, coordY, markName, type ) );


Your file handling is also specious. Lines 13 and 14 create new, unassigned file streams. 'inFile' will never be open on line 16. You don't need 'inFile' anyway. (BTW, you also fail to return a value from the function.) Here is an example function that takes an existing file (supposedly already opened) and writes a mark to it. It outputs the same way your function does.

1
2
3
4
5
6
7
void write_mark_to_file( ofstream& file, mark_t mark )
  {
  if (!file.is_open()) ...

  file << mark.name << " - " << mark.type << endl;
  file << mark.x    << ", "  << mark.y    << endl;
  }

This creates a file like:

mark 1 - bubble
10, 72
markus - top dog
99, 100

Notice that the marks are spread over two lines in your text file. A simple CSV kind of layout might suit you better...

If you overload your 'mark_t' operators properly, you can read and save an entire set of marks, or just one mark, easily. Here are a couple of CSV file handling links that may help you, in order of most relevance.

http://www.cplusplus.com/forum/beginner/28109/#msg151349
http://www.cplusplus.com/forum/general/17771/#msg89751

Obviously, you can easily change how a mark is read from and written to file, if you want to keep your two-line method. Also keep in mind that when you let the user name your mark and its type without any validation, the user can type things in that will make it very hard to separate the mark name and type when you read it back from file.

Hope this helps.
Wow! You're a life saver!

So, using a struct would be like putting arguments inside of an argument?

and, I don't understand what you're doing here:

In any case, you then need to make your routine properly handle a mark. You can create a constructor for your mark:

1
2
3
4
5
6
7
struct mark_t
  {
  ...
  mark_t( unsigned x, unsigned y, const string& name, const string& type ):
    name( name ), type( type ), x( x ), y( y )
    { }
  };


Adding a mark to the 'array' is then simple:

1
2
cin >> coordY;
    marks.push_back( mark_t( coordX, coordY, markName, type ) );

1
2
3
4
5
6
7
struct mark_t
  {
  ...
  mark_t( unsigned x, unsigned y, const string& name, const string& type ):
    name( name ), type( type ), x( x ), y( y )
    { }
  };

http://stackoverflow.com/questions/2785612/c-what-does-the-colon-after-a-constructor-mean/2785639#2785639

1
2
cin >> coordY;
    marks.push_back( mark_t( coordX, coordY, markName, type ) );

http://cplusplus.com/reference/stl/vector/push_back/
Topic archived. No new replies allowed.