Reading from a file into a Struct

Hi, and thanks for looking.

What I am trying to do is have a struct and read from a file and output it to screen and file.

Here is the code (just really basic to get the point)

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
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>

using namespace std;

struct list
{
	string name;
} student;


int main ()
{
	ifstream inFile;
	ofstream outFile;

	inFile.open("student-input.txt");
	outFile.open("student-output.txt");

	cout << "Processing data" << endl;

	inFile >> student.name;
	outFile << "Student name: " << student.name << endl;

	cout << "Student name: " << student.name;

	inFile.close();
	outFile.close();

	cin.get(); //to keep visual c++ open
	return 0;
}


Alright the error I get is

1>------ Build started: Project: Struct2, Configuration: Debug Win32 ------
1>Compiling...
1>struct.cpp
1>Linking...
1>MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup
1>C:\Users\Nightmare\Documents\Visual Studio 2008\Projects\Struct2\Debug\Struct2.exe : fatal error LNK1120: 1 unresolved externals
1>Build log was saved at "file://c:\Users\Nightmare\Documents\Visual Studio 2008\Projects\Struct2\Struct2\Debug\BuildLog.htm"
1>Struct2 - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

and I am not sure where that is? When I click to go to error on the link, it just highlights the line in the log and not in the code.

My text file is basic

Richard

saved in the file in the folder under projects.

I can get reading from a file to work in just main with no structs but not able to do this. Any tips would be appreciated.

Thanks
Akumanight
First of all, defining a class and then declaring an object of it immediately thereafter - in the same statement - is poor style. It makes it unclear what you are actually doing or trying to accomplish. Brevity is one thing, but that's another.
Second, I notice you use both an ifstream and an ofstream. I would suggest you instead use an fstream object and set it to both input and output. The consequence is that the cursor in the file will move for both operations. If you need to read from one place and write to another your current arrangement is fine. But if you read and write from the same area, a dual-purpose fstream is more efficient.
Now then I see you're using VC++ and I'm going to ask you a question before I analyze your code, because this has honestly happened to me before:
When you created your project, did you set it as a windows application or a windows console application? If you did the former, that explains the error about winmain. It's expecting windows API code. Copy your source file and put it in a console project. (This is an honest mistake that I've made and it's inexplicable, don't feel bad)
That's probably the source of your only error.
Your program compiles just fine in g++. Perhaps this is an error with the Microsoft linker?

My highly personal advice is to try the gnu compiler instead.
VC++ is perfectly fine. I'm not going to say that *is* his error but I've seen that before and I am pretty sure what it is. It's just because the program expects windows API code - which calls WinMain and not main. Because the project may be expecting winapi code it is not ready for a normal console prog. Which is why it compiles fine normally. If you aren't sure what IDE to use check this article: http://www.cplusplus.com/forum/articles/7263/
Eclipse is undoubtedly one of the highest, although I still use VC++ for... some reason...
Last edited on
There's nothing wrong with declaring an object along with the class.

Second, he STL file stream classes do not make file pointer updates for read and write match. That is an artifact of implementation. (IIRC, C++0x addresses the issue to mandate that the read and write pointers be disjoint.) Also, he's operating over two distinct files -- so there is little point in trying to combine them. One fstream object per stream is the correct way to do it.

The point about the project type is correct. From the File menu, start a New Project and specify that it be a Console Application. Copy and paste your code into the new application's edit window and save and compile.

There is nothing wrong with his choice of compiler.


For I/O with classes, you should overload the operators that do it. In your case:
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
#include <iostream>
#include <limits>
#include <string>
using namespace std;

struct Student  // it is not a list ... it is a single student
{
  string name;
};

istream& operator >> ( istream& ins, Student& student )
{
  ins >> student.name;
  return ins;
}

ostream& operator << ( ostream& outs, const Student& student )
{
  outs << student.name;
  return outs;
}

int main ()
{
  Student the_student;

  ...

  infile >> the_student;
  outfile << "Student name: " << the_student.name << endl;

  ...

  cout << "Press ENTER to quit..." << flush;
  cin.ignore( numeric_limits <streamsize> ::max(), '\n' );
  return 0;
}

You might also want to consider student names that are multiple words, like "John Jones", and use getline() to read an entire line of text instead of a single word.

Hope this helps.
I know there's nothing syntactically wrong with declaring an object of a class in the same statement that defines the class. But I personally find that compromises the legibility of the code and it can be hard to spot at first read. If you comment it to make your objective clear, fair enough.
EDIT: By the way Duoas, I'm really looking forward to that issues in console programming article, when is the next time you are planning to edit it? Sorry to sound impatient, I kind of am...
Last edited on
In my opinion, declaring an instance of a class/struct in the same statement is poor style--or at least poor OOP style. There's nothing syntactically wrong with it and styles do, of course, vary. However, in this example, student is being declared globally rather than inside the scope of main, where it is used.
I agree with Duaos. That's like saying that you shouldn't declare more than one variable per line.
In my opinion, declaring an instance of a class/struct in the same statement is poor style--or at least poor OOP style.
What?
I think I do have to retract some.

Yes, it is OK to declare and instanciate in one breath. I don't like always/never rules. (I had written a bit longer of a post, but then I accidentally hit Ctrl-R and lost it all. [Ctrl-Q,R is Wordstar command for "go to top of document"])

However, it typically is a good idea to keep type definitions and object declarations separate. People expect it, and it helps organize your code. Further, it helps remove the temptation to do stupid stuff.

The most important thing is clarity and maintainability.


As for the issues in console programming, I would very much like to post more, but ATM I am exceedingly busy with other things. I don't know how soon I'll be able to update. The article I'm working on right now is important, but a bit hairy, and somewhat boring to me. Also, with the new Articles section, and the changes in BBCode that have affected the initial articles, I'm reconsidering how I wish to format them. (Just technical stuff, not content.)

Most currently I'm revisiting the toy language thread I started some time ago. Perhaps you'll see some of that first. (But who knows? I am awfully occupied right now.)

Alas.
And I'll also throw in my 2 cents (as if it matters) and say it's in bad form to define and declare in the same statement.

Being a lazy coder will end up biting you in the rump sooner or later. Even if you have to add a few extra lines here and there, it's better for clarity.
I want to thank all of you for the very fast tips and answer. I don't know how many times I remake and test code but one usually thinks that at least you open it correctly, but sometimes. I did remake the project and made sure that it was under Console and then it worked just fine. Next time when I get that error, I will certainly try that first. And I thank you Duoas for the extra tip on to write the overload. They will be more data that will be going into the struct I just needed the reason why the error was showing up.

Thanks again
Akumanight
Topic archived. No new replies allowed.