-
Trying to create a vector using a structure definition as the basis in VC++
I was trying to apply what is here (as someone who writes rarely and has to relearn everything each time):
http://www.daniweb.com/software-deve...ctor-of-struct
I'm using a header file to define the structure:
#ifndef EINSTEIN_H
#define EINSTEIN_H
#include <stdio.h>
#include <vector>
struct SizeAll{
double year;
double R;
SizeAll() { year = 0; R = 0; }
};
int write_to_file(int count, struct SizeAll *data, char const
*fileName)
{
FILE* fp;
fp = fopen(fileName, "w");
if (fp == NULL) return -1;
while (count-- > 0) {
fprintf(fp, "%d,%d\n", data->year, data->R);
//check for errors writing to file
if (ferror(fp)) return -1;
}
fclose(fp);
return 0;
}
#endif
I've loaded the following in the "main.cpp" equivalent. (Not called "main.cpp", but serves the same purpose.)
#include "stdafx.h"
#include <vector>
#include <stdio.h>
#include "Einstein.h"
#include <math.h>
#include "Form1.h"
The code that actually seeks to generate the vector using the structure definition follows:
int counter,year,retval,count;
vector<SizeAll> Universe;
Universe.resize(5);
vector<SizeAll> *heretis;
char const NameFile[]="D:\\Friedout.csv";
heretis=&Universe;
Universe.R = double(366);
Universe.year = double(188);
for ( counter = 15000 ; counter > 99 ; counter-- )
{
Universe.year =double(counter);
Universe.R = double(counter*2);
if (counter==100||counter ==2500||counter==5000||counter==7500||counter==10000||counter==12500||counter==15000)
{
retval=write_to_file(1, heretis, NameFile);
if (retval ==-1)
{
break;
}
}
}
This creates quite a mess. It seems that somehow the "vector" declaration isn't working as the referenced web link seems to suggest that it should. I presume that, as usual, clearing one real error will eliminate the cascade of errors the first real error produces. Can anyone clear this up for me? Why won't VC++ accept the "vector" identifier? Thank you.
The error messages that follow the build attempt are:
Friedman.cpp
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Einstein.h(22): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files\Microsoft Visual Studio 10.0\VC\include\stdio.h(234) : see declaration of 'fopen'
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(80): warning C4067: unexpected tokens following preprocessor directive - expected a newline
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(82): error C2065: 'vector' : undeclared identifier
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(82): error C2275: 'SizeAll' : illegal use of this type as an expression
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Einstein.h(9) : see declaration of 'SizeAll'
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(82): error C2065: 'Universe' : undeclared identifier
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(83): error C2065: 'Universe' : undeclared identifier
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(83): error C2228: left of '.resize' must have class/struct/union
type is ''unknown-type''
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(84): error C2065: 'vector' : undeclared identifier
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(84): error C2275: 'SizeAll' : illegal use of this type as an expression
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Einstein.h(9) : see declaration of 'SizeAll'
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(84): error C2065: 'heretis' : undeclared identifier
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(87): error C2065: 'heretis' : undeclared identifier
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(87): error C2065: 'Universe' : undeclared identifier
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(88): error C2065: 'Universe' : undeclared identifier
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(88): error C2228: left of '.R' must have class/struct/union
type is ''unknown-type''
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(89): error C2065: 'Universe' : undeclared identifier
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(89): error C2228: left of '.year' must have class/struct/union
type is ''unknown-type''
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(92): error C2065: 'Universe' : undeclared identifier
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(92): error C2228: left of '.year' must have class/struct/union
type is ''unknown-type''
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(93): error C2065: 'Universe' : undeclared identifier
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(93): error C2228: left of '.R' must have class/struct/union
type is ''unknown-type''
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(96): error C2065: 'heretis' : undeclared identifier
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Quote:
Originally Posted by
Protocol
Please use code tags when posting code. You were told how to do that in other threads. The code you posted is unreadable without them.
Regards,
Paul McKenzie
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Vector is part of the std namespace. Try inserting after your includes:
Code:
using namespace std;
-
Re: Trying to create a vector using a structure definition as the basis in VC++
You have code that's not inside a function.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Paul,
Would you please give me the information I need to use these "code tags"? I'm not used to employing them. I'm using Chrome as a browser, if that has any effect. Thank you.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
2kaud,
Thank you for the useful input. I've applied it, and it does seem to at least change the error messages I'm getting.
I have some additional questions for you, if you happen to be able to favor me with a response. Thank you.
1. What does "using namespace std;" do? I ask, because this is a "managed code" project, and the managed code that produces the form for Windows under VC++ 2010 is also referencing a DIFFERENT namespace. The VC++ managed code namespace reference is right where you told me to put the std namespace reference. It is in the "main.cpp" equivalent, and it looks like:
(Imagine this is in "code tags", please...)
// Friedman.cpp : main project file.
#include "stdafx.h"
#include <vector>
#include <stdio.h>
using namespace std;
#include "Einstein.h"
#include <math.h>
#include "Form1.h"
using namespace Friedman;
As you can see, it references the name of the "solution/project", which is Friedman, as the "namespace". I don't understand "namespace" as a reference, so I don't know if I'm stepping on toes with the "std namespace" reference.
2. I'm getting a new batch of errors, but they seem less obstinate than the first. Honestly, I haven't given them a great deal of thought yet, since I'm a little nervous regarding my lack of understanding of what I've actually done by incorporating two "namespace" references in the "main.cpp" equivalent.
ERRORS from "build" attempt:
------ Build started: Project: Friedman, Configuration: Debug Win32 ------
Friedman.cpp
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Einstein.h(22): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files\Microsoft Visual Studio 10.0\VC\include\stdio.h(234) : see declaration of 'fopen'
d:\documents and settings\del ventruella\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(88): error C2039: 'R' : is not a member of 'std::vector<_Ty>'
with
[
_Ty=SizeAll
]
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(89): error C2039: 'year' : is not a member of 'std::vector<_Ty>'
with
[
_Ty=SizeAll
]
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(92): error C2039: 'year' : is not a member of 'std::vector<_Ty>'
with
[
_Ty=SizeAll
]
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(93): error C2039: 'R' : is not a member of 'std::vector<_Ty>'
with
[
_Ty=SizeAll
]
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(96): error C2664: 'write_to_file' : cannot convert parameter 2 from 'std::vector<_Ty> *' to 'SizeAll *'
with
[
_Ty=SizeAll
]
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
-
Re: Trying to create a vector using a structure definition as the basis in VC++
2kaud,
Thank you for the useful input. I've applied it, and it does seem to at least change the error messages I'm getting.
I have some additional questions for you, if you happen to be able to favor me with a response. Thank you.
1. What does "using namespace std;" do? I ask, because this is a "managed code" project, and the managed code that produces the form for Windows under VC++ 2010 is also referencing a DIFFERENT namespace. The VC++ managed code namespace reference is right where you told me to put the std namespace reference. It is in the "main.cpp" equivalent, and it looks like:
(Imagine this is in "code tags", please...)
// Friedman.cpp : main project file.
#include "stdafx.h"
#include <vector>
#include <stdio.h>
using namespace std;
#include "Einstein.h"
#include <math.h>
#include "Form1.h"
using namespace Friedman;
As you can see, it references the name of the "solution/project", which is Friedman, as the "namespace". I don't understand "namespace" as a reference, so I don't know if I'm stepping on toes with the "std namespace" reference.
2. I'm getting a new batch of errors, but they seem less obstinate than the first. Honestly, I haven't given them a great deal of thought yet, since I'm a little nervous regarding my lack of understanding of what I've actually done by incorporating two "namespace" references in the "main.cpp" equivalent.
ERRORS from "build" attempt:
------ Build started: Project: Friedman, Configuration: Debug Win32 ------
Friedman.cpp
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Einstein.h(22): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C:\Program Files\Microsoft Visual Studio 10.0\VC\include\stdio.h(234) : see declaration of 'fopen'
d:\documents and settings\del ventruella\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(88): error C2039: 'R' : is not a member of 'std::vector<_Ty>'
with
[
_Ty=SizeAll
]
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(89): error C2039: 'year' : is not a member of 'std::vector<_Ty>'
with
[
_Ty=SizeAll
]
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(92): error C2039: 'year' : is not a member of 'std::vector<_Ty>'
with
[
_Ty=SizeAll
]
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(93): error C2039: 'R' : is not a member of 'std::vector<_Ty>'
with
[
_Ty=SizeAll
]
d:\documents and settings\xx\my documents\visual studio 2010\projects\friedman\friedman\Form1.h(96): error C2664: 'write_to_file' : cannot convert parameter 2 from 'std::vector<_Ty> *' to 'SizeAll *'
with
[
_Ty=SizeAll
]
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Thank you for your understanding regarding the appearance of some of this data.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Quote:
Originally Posted by
Protocol
1. What does "using namespace std;" do?
Namespaces are fundamental to C++. The very first C++ program you write uses this.
Code:
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World";
}
This is a basic "Hello World" program in C++. Without the namespace, the code will not compile due to "cout" not being found.
Quote:
(Imagine this is in "code tags", please...)
Why "imagine"? I already stated in another thread how to use code tags. Once again:
[code]
Your code goes here
[/code]
Second, are you trying to learn C++ by writing things and seeing what sticks? Well, C++ can't be learned that way. You need to get a book or tutorial and go through the basics of the language. It isn't the same as learning HTML or some other script or script-like language, where all you need is an hour and a cheat sheet to help you out.
Regards,
Paul McKenzie
-
Re: Trying to create a vector using a structure definition as the basis in VC++
No, I'm not trying to learn C or C++ from scratch, but I've never tried to create a vector of structures before, and haven't written anything in C or C++ for years. Passing a vector of structure to a subroutine in a header file is also new to me. Neither of these topics were specifically covered in the beginner course in "C" that I completed via a local university. In general, I hope to learn more by creating code and building on what I already know, with some help from others who are willing to assist.
Tutorials typically don't provide detailed guidance for the specific problems I'm now dealing with. The course I completed in "C" certainly didn't. I've already searched the web relative to these matters repeatedly, as I indicated. I'm seeking guidance, from knowledgeable parties, who actually sound and act like they're willing to provide helpful insights. That can help me to move beyond the basics, and overcome what I may have lost over the years away from "C" (such as a facility with pointer variables). Is there some reason you're inclined to seek to deter my effort to improve my grasp of C/C++ by discouraging me from posting on this site? First you insist that "managed" VC++ code has no place in the "VC++ forum". Now I seem to face what is being expressed as a more fundamental issue with my presence here. I certainly have no intent to specifically burden any party, individually, with my questions.
If anyone has a few moments and no inclination toward focusing resentment at those trying to move beyond the basics, and to achieve a better grasp of certain "basics", I'd love to know what a "namespace" is and how referencing two of them as I've done (please see below) might affect the code I've written. I'd certainly appreciate any insightful response in that regard.
To keep things up to date (and formatted in conformance with local standards), the code I'm using to seek to create and pass a vector containing structured data elements follows (and is contained within a "form" in the code I've written):
Code:
int counter,year,retval,count=0;
vector<SizeAll> Universe;
Universe.resize(5);
vector<SizeAll> *heretis;
char const NameFile[]="D:\\Friedout.csv";
heretis=&Universe;
Universe[0].R = double(366);
Universe[0].year = double(188);
for ( counter = 15000 ; counter > 99 ; counter-- )
{
if (counter==100||counter ==2500||counter==5000||counter==7500||counter==10000||counter==12500||counter==15000)
{
Universe[count].year =double(counter);
Universe[count].R = double(counter*2);
count = count + 1;
retval=write_to_file(1, heretis, NameFile);
if (retval ==-1)
{
break;
}
}
}
The header file that contains the structure definition and the subroutine that is meant to create a file containing data passed from the preceding code is now defined as:
Code:
#ifndef EINSTEIN_H
#define EINSTEIN_H
#include <stdio.h>
#include <vector>
using namespace std;
struct SizeAll{
double year;
double R;
SizeAll() { year = 0; R = 0; }
};
int write_to_file(int count, vector<SizeAll> *data, char const
*fileName)
{
FILE* fp;
fp = fopen(fileName, "w");
if (fp == NULL) return -1;
while (count-- > 0) {
fprintf(fp, "%d,%d\n", data[0].year, data[0].R);
//check for errors writing to file
if (ferror(fp)) return -1;
}
fclose(fp);
return 0;
}
#endif
The header file "include" statements remain as follows (for now, pending further insight into "namespaces":
Code:
// Friedman.cpp : main project file.
#include "stdafx.h"
#include <vector>
#include <stdio.h>
using namespace std;
#include "Einstein.h"
#include <math.h>
#include "Form1.h"
using namespace Friedman;
My thanks to anyone who cares to take a look and make a response. At this time, it appears that the "build" is generating errors suggesting that the vector of structured data that I'm passing with a pointer is not being properly referenced. (It is not recognizing the structure variables because they aren't associated with indices and are not defined in the "class". Simply adding vector indices doesn't seem to solve the problem. This leaves me to question whether passing the pointer variable is enough to permit me to access the vector of structured data in the Einstein.h header file subroutine. Is there a way to deal with this? Originally, I referenced the data using pointers in the Einstein.h header file subroutine. Now the "build" is saying it can't do this with the vector of structured data, and asks if I wish to use a "." to reference the structure elements.
Have a nice day!
-
Re: Trying to create a vector using a structure definition as the basis in VC++
The using directive allows the names in a namespace to be used without the namespace-name as an explicit qualifier. If a name is defined in a namespace then it must be referenced via that namespace name. The namespace of the c++ standard library is std. Therefore all references to names from the standard library (such as string, vector) need to be preceeded by std:: such as
Code:
#include <vector>
int main()
{
std::vector<int> intvec;
return 0;
}
The using directive means that the explicit namespace need not be specified as
Code:
#include <vector>
using namespace std;
int main()
{
vector<int> intvec;
return 0;
}
If Friedman is the name of the "solution/project" then this is not a namespace and hence
using namespace Friedman;
is incorrect and should not be included.
Quote:
You need to get a book or tutorial and go through the basics of the language. It isn't the same as learning HTML or some other script or script-like language, where all you need is an hour and a cheat sheet to help you out.
Paul is absolutely correct. c++ is a very complex language. You just can't 'wing it' as you go along and hope for the best. You must start with the simple basics and only advance one step when you understand the current step.
Incidentially, you mention that this is a 'managed code' project. This forum is not for managed code. There is another forum which deals with managed code. People on this forum can't help with managed code issues.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Quote:
Originally Posted by
Protocol
No, I'm not trying to learn C or C++ from scratch,
Which is the whole problem.
How are you going to learn the advanced topics if you don't know the basics, such as namespaces? You can't cherry-pick certain topics in C++ and expect to get anything useful done. You have to know the basics before going on to do anything else in C++.
Quote:
Passing a vector of structure to a subroutine in a header file is also new to me.
Passing vector is no different than passing any other parameter type. You have pass-by-value, and pass-by-reference, again, no different than any other type.
Quote:
Neither of these topics were specifically covered in the beginner course in "C" that I completed via a local university.
That is because C++ is not 'C'. The two are separate languages, and knowing C does not make you experienced in C++ or have the "inside track" to learning C++.
Quote:
If anyone has a few moments and no inclination toward focusing resentment at those trying to move beyond the basics, and to achieve a better grasp of certain "basics", I'd love to know what a "namespace" is
http://www.cplusplus.com/doc/tutorial/namespaces/
www.parashift.com
Quote:
To keep things up to date (and formatted in conformance with local standards), the code I'm using to seek to create and pass a vector containing structured data elements follows (and is contained within a "form" in the code I've written):
The way you learn is to write smaller programs so that you become familiar with the topic.
Code:
#include <vector>
#include <vector>
#include <iostream>
struct foo
{
int x;
int y;
foo(int x_=0, int y_=0) : x(x_), y(y_) {}
};
typedef std::vector<foo> FooVector;
void SomeFunction(FooVector& fV)
{
fV.push_back(foo(10, 20));
}
using namespace std;
int main()
{
FooVector v;
SomeFunction( v );
cout << v[0].x << ", " << v[0].y;
}
These are the types of small programs you should be writing so that you become familiar with the topic.
Regards,
Paul McKenzie
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Thank you, 2kaud. I believe that if you'll check the content that is relevant to what I'm asking, there is no specific reference to the "managed code" generated by VC++. I'm seeking to debug a program strictly relative to passing a vector of structured data using a pointer. (How can that be "managed code" specific, or even relevant?)
Based on your prior response. I presume that one could have two namespaces, without necessarily confusing the compiler, unless there are duplicate definitions in each namespace?
Thanks!
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Dear Mr. McKenzie:
Thank you for that bit of code. I'll be reviewing and enjoying it this evening.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
This compiles under VS taken from your code.
Code:
#include <vector>
using namespace std;
struct SizeAll{
double year;
double R;
SizeAll() { year = 0; R = 0; }
};
int write_to_file(int count, const vector<SizeAll>& data, char const *fileName)
{
FILE* fp;
fp = fopen(fileName, "w");
if (fp == NULL) return -1;
while (count-- > 0) {
fprintf(fp, "%d,%d\n", data[0].year, data[0].R);
//check for errors writing to file
if (ferror(fp)) return -1;
}
fclose(fp);
return 0;
}
int main()
{
int counter,
retval,
count=0;
char const NameFile[]="D:\\Friedout.csv";
vector<SizeAll> Universe;
vector<SizeAll> *heretis;
Universe.resize(5);
heretis=&Universe;
Universe[0].R = double(366);
Universe[0].year = double(188);
for ( counter = 15000 ; counter > 99 ; counter-- ) {
if (counter==100||counter ==2500||counter==5000||counter==7500||counter==10000||counter==12500||counter==15000) {
Universe[count].year =double(counter);
Universe[count].R = double(counter*2);
count = count + 1;
retval=write_to_file(1, Universe, NameFile);
if (retval == -1) {
break;
}
}
}
return 0;
}
Why are you using heretis as a pointer to vector<SizeAll> then setting address to Universe?
Incidentially, instead of using vector<SizeAll> everywhere, you can define a typedef for this as
Code:
typedef vector<SizeAll> SizeVec;
Then whereever you use vector<SizeAll> you can then just use SizeVec
Code:
int write_to_file(int count, const SizeVec& data, char const *fileName)
...
SizeVec Universe;
SizeVec *heretis;
-
Re: Trying to create a vector using a structure definition as the basis in VC++
The whole point of having namespaces is so that you don't have name clashes. c++ comes with a string class defined in the std namespace. If I want my own class called string I can create a new namespace called say myspace and define my implementation of string within this namespace. As the namespaces are different, there is no conflict of names which there would be if namespaces were not used.
Code:
std::string stdstring;
myspace::string mystring;
This problem of conflicting names is particularly problematic if you obtain libraries from 3rd parties.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
I don't want to interfere with all the things that already have been stated correctly, but I think I should clarify (at least superficially) some things about the relation between native C++ and managed C++ (IOW C++/CLI) before even more confusion arises...
Quote:
Originally Posted by
2kaud
If Friedman is the name of the "solution/project" then this is not a namespace and hence
using namespace Friedman;
is incorrect and should not be included.
That's not exactly true for Windows Forms application projects. When the VC++ IDE sets up such a project, it creates a namespace with the same name as the as the project. I usually call that the "application namespace", but I think that's by no means an official term. The main form class (Form1) is defined in that namespace, but for any other classes (except for forms created by the IDE), the developers need to take care of that themselves.
Quote:
Originally Posted by
Paul McKenzie
How are you going to learn the advanced topics if you don't know the basics, such as namespaces? You can't cherry-pick certain topics in C++ and expect to get anything useful done. You have to know the basics before going on to do anything else in C++.
[...]
So true, so true... While not even native C++ really is a language meant for beginners, C++/CLI is even less. One might say that C++ is a language for those who know what they're doing, and C++/CLI is one for those who know even better. (By which I don't mean to say that C++/CLI is in any way superior to native C++. But it definitely is more demanding in some aspects.)
One word directly to the OP, Protocol: MFC is sort of the canonical way of writing native C++ Windows GUI apps, but the Express Edition doesn't provide that. So the only way to write Windows GUI applications with the Express, except for Petzold-Style raw Win32 programming (rather tideous) or 3rd-party libraries, is Windows Forms. But if you pick that, stick with it. Mixing managed and native code in C++/CLI is possible, and in fact the probably primary advantage of C++/CLI, but it's strongly discouraged unless you have a really good reason to do that, especially for beginners. Such combinations result in "interop scenarios" which can be really, really advanced and cause unexpected and complicated difficulties.
If you make your decision for Windows Forms and C++/CLI, feel free to post in the dedicated forum section. But, as already mentioned, I strongly recommend against mixing that with native C++ without a good reason.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Thanks for actually going so far as to run this code through your compiler. (I don't understand how your middle term would work to pass meaningful data to the function. It looks like a memory address is defined in the function, but you pass the name of the vector of structured data.)
I've tried a few things tonight. Although they compile, they do not produce any data saved in the output file that is predictable. I'd expect to see 188 and 366 separated by a comma in five, vertically stacked lines of data pairs. What I get looks like digital noise from the memory, instead, when I compile the following.
HEADER:
Code:
#ifndef EINSTEIN_H
#define EINSTEIN_H
#include <stdio.h>
#include <vector>
using namespace std;
struct SizeAll{
double year;
double R;
SizeAll() { year = 0; R = 0; }
};
typedef vector<SizeAll> SizeVector;
int write_to_file(int flag, SizeVector data, char const
*fileName)
{
int count = 0;
FILE* fp;
fp = fopen(fileName, "w");
if (fp == NULL) return -1;
while (count++ < flag) {
fprintf(fp, "%d,%d\n", data[0].year, data[0].R);
//check for errors writing to file
if (ferror(fp)) return -1;
}
fclose(fp);
return 0;
}
#endif
LOADING HEADERS INTO MAIN
Code:
// Friedman.cpp : main project file.
#include "stdafx.h"
#include <vector>
#include <stdio.h>
using namespace std;
#include "Einstein.h"
#include <math.h>
#include "Form1.h"
using namespace Friedman;
CALLING ROUTINE
Code:
int counter=0,year=0,retval=0,count=0;
SizeVector Universe;
Universe.resize(5);
SizeVector *heretis;
char const NameFile[]="D:\\Friedout.csv";
heretis=&Universe;
Universe[0].R = double(366);
Universe[0].year = double(188);
for ( counter = 15000 ; counter > 99 ; counter-- )
{
if (counter==100)//||counter ==2500||counter==5000||counter==7500||counter==10000||counter==12500||counter==15000)
{
//Universe[count].year =double(counter);
//Universe[count].R = double(counter*2);
count = count + 1;
retval=write_to_file(5, Universe, NameFile);
if (retval ==-1)
{
break;
}
}
}
-
Re: Trying to create a vector using a structure definition as the basis in VC++
You're still using the wrong format specifier in your fprintf() call. %d is for integers, not for doubles.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Why would you expect to see the output you want? The program doesn't do this!
Your specific assignments
Code:
Universe[0].R = 366.0;
Universe[0].year = 188.0;
are overwritten by
Code:
Universe[count].year = double(counter);
Universe[count].R = double(counter * 2);
as count starts at 0!
Assuming you use the right format specifier in fprintf, the data you'll get in the file is
15000.0,30000.0
15000.0,30000.0
15000.0,30000.0
15000.0,30000.0
15000.0,30000.0
which is correct for your program logic!
In the function definiton
Code:
int write_to_file(int count, const vector<SizeAll>& data, char const *fileName)
data is being passed as a reference - not as a memory address. This is a c++ concept. As Paul has repeatly stated
Quote:
you can't cherry-pick certain topics in C++ and expect to get anything useful done. You have to know the basics before going on to do anything else in C++.
The code that produced the above output is
Code:
#include <vector>
using namespace std;
struct SizeAll {
double year;
double R;
SizeAll() : year(0.0), R(0.0){};
};
typedef vector<SizeAll> VecSize;
int write_to_file(int count, const VecSize& data, char const *fileName)
{
FILE* fp;
if ((fp = fopen(fileName, "w")) == NULL)
return -1;
while (count--) {
fprintf(fp, "%.1f,%.1f\n", data[0].year, data[0].R);
//check for errors writing to file
if (ferror(fp))
return -1;
}
fclose(fp);
return 0;
}
int main()
{
int counter,
retval,
count=0;
char const NameFile[]="d:\\Friedout.csv";
VecSize Universe(5);
Universe[0].R = 366.0;
Universe[0].year = 188.0;
for ( counter = 15000 ; counter > 99 ; counter-- ) {
if (counter == 100 || counter == 2500 || counter == 5000 || counter == 7500 || counter == 10000 || counter == 12500 || counter == 15000) {
Universe[count].year = double(counter);
Universe[count].R = double(counter * 2);
count++;
retval = write_to_file(5, Universe, NameFile);
if (retval == -1) {
break;
}
}
}
return 0;
}
Hope this helps.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
I truly appreciate your responses.
I'll work on the code later on today and let you know if the modifications you suggest repair the problem.
I'd like to build a grasp of working techniques in code that functions, from which I can borrow methods for use in the future. I last tried C++ with CodeWarrior for Palm. I found that after a while I was no longer going to the forum for that software and was developing the program rather smoothly. At that time I learned quite a bit about issues of instantiating and freeing up memory space with variables while debugging in the Palm emulator.
I've tried a little Borland Builder C++, but that went down the tube with Borland, and I couldn't justify spending fifteen hundred dollars for the professional edition with no anticipation of programming professionally. I saw that Microsoft had a free version of VC++, and decided to use it.
I did complete one graduate course in C++ as directed study to produce a template base class to perform matrix manipulation. That was in 1997. Things have happened since, and my memory is not what it was immediately after I completed the MSEE. Sorry if I seem to be a bother, but I do appreciate your assistance. (I was a little too tired last night to dig into the logic of the code after it compiled.)
I've lost a lot of what I once knew with regard to C++ after writing that template class. Typically I regain it if I focus on developing code for a while, but it fades in the subsequent years, and I'm back to where I am now.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Oh great 2kaud! You seem to have failed to quote from the very post of mine that contains the changes that made me anticipate the outcome that I referenced, although you did read the portion in which I express my disappointment due to the result being unpredictable! Instead, you quote from slightly more stale code below! No worries... Your time is valuable, and such minor points don't bother me a bit given your clever insight. Why read another long code statement if you've already brilliantly determined the true cause of the unpredictability?
Quote:
Originally Posted by
2kaud
Why would you expect to see the output you want? The program doesn't do this!
Your specific assignments
Code:
Universe[0].R = 366.0;
Universe[0].year = 188.0;
are overwritten by
Code:
Universe[count].year = double(counter);
Universe[count].R = double(counter * 2);
as count starts at 0!
[/CODE]
Hope this helps.
Yes, great 2kaud! It helped! It solved the problem. I needed merely to insert your format mask, and what happened? The code ran predictably. (See, I'm even remembering terms like "mask" on only my second day with the software...) I'd experimented with "%d" and "%f", and only seen that the results eliminated the decimal in the former. That was fine, since I'm dealing with billions of years in the output, and massive volumes. I do need to find an easily comprehensible reference on output formats that include "%lf", because I don't specifically recall using that one in the past, although the C instructor probably managed to slip it in somewhere, two decades ago.
I used your output format for the file:
Code:
fprintf(fp, "%.1f,%.1f\n", data[0].year, data[0].R);
and it ran like a charm!
All hail, 2kaud! Insightful! Helpful! Radiant keeper of C++ useful brilliance, divine software insight, and Olympian Coder (or "OC" for short)!
(Okay, maybe that was a little thick...)
Thank you!
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Quote:
Originally Posted by
Protocol
I needed merely to insert your format mask, and what happened? The code ran predictably.
If you used C++ streams, then there is no issue of using the correct format statement.
Code:
#include <fstream>
//...
std::ofstream outfile("name_of_output_file");
//...
outfile << data[0].year << "," << data[0].R;
The printf() family of functions are discouraged from use due to being non-typesafe, leading to runtime errors. The streams automatically convert the type to the appropriate string to be outputted.
Also, gcc has made free compilers for many years now. You never needed to spend money on Borland Builder or any such compiler when there was a completely free one (that is used in many commercial programs and by many companies) out there all along.
Regards,
Paul McKenzie
-
Re: Trying to create a vector using a structure definition as the basis in VC++
If anyone knows of a particularly good (free) downloadable e-book (in pdf, or e-book format) that I might download on programming in C++ that is compatible with VC++ and offers fundamental guidance relative to how to build code in C/C++, would you please pass the web link along? I have a slow internet connection, and the VC++ help for my express version of the software simply sends me to the Microsoft Developer website. It might be useful to have a searchable e-book on my desktop in which I can seek guidance next time I need to select an output mask...
I have one, Borland, programming in C++ for Windows books left on my shelf, and it is decades out of date. (I have three books on programming for Palm OS - but that pesky Android OS just HAD to come along... I should probably re-assign myself the problem of writing a template base class and try to work my way back through it again.)
Thanks to all who helped out here!
-
Re: Trying to create a vector using a structure definition as the basis in VC++
-
Re: Trying to create a vector using a structure definition as the basis in VC++
1. Thanks, I'll take a look, but if anyone has already done that and knows of a particularly insightful e-tome that I can download on C/C++ (or VC++), I'd certainly appreciate the name and link.
2. I started working on this software again this morning after spending yesterday helping an elderly relative get out of the house for a little while to attend to some personal matters. I was able to produce a file that contained all but the highest valued output just as I wanted it, but I could not induce the code to generate the highest valued output. Now the code is simply locking up and producing no file. (I had thought it was continuing to generate a file each time that I tweaked it, but found that, instead, only the first file remained on my "D:" drive directory.)
I know that with VB it was not that difficult to debug the code in a mode that let me induce the IDE to mark each line of code as it was being executed while testing. That enabled me to find the point at which the errors were occurring or where the code was trapped in a loop. I'd prefer to only trace code lines after the build, rather than each line related to generating a form produced as managed code by VC++. Can anyone advise me with regard to the proper approach by which to cause VC++ (express) to first build the file, then begin to trace the code lines as they are implemented on-screen? (I'll add the latest version of my code below, in case anyone cares to seek the error simply via inspection. I'll be further along and more insightful in terms of being able to see where my code is going wrong when I can again "watch" variable values and concurrently see each line of the code indicated that is executed marked on-screen while debugging, as I did with VB 5.0. I tried to put a variable in the "watch" window, but because VC++ was busy building the file, I had to step through a great deal of managed code that was being executed while that variable was "out of scope" for the code that was being run by VC++.) Thank you.
"Main.cpp" code header file load follows
Code:
// Friedman.cpp : main project file.
#include "stdafx.h"
#include <vector>
#include <stdio.h>
using namespace std;
#include "Einstein.h"
#include <math.h>
#include "Form1.h"
using namespace Friedman;
ROUTINE THAT CALLS FUNCTION IN EINSTEIN.H TO PRODUCE OUTPUT CSV FILE
Code:
//BEGINNING OF CODE WRITTEN TO IMPLEMENT COMPUTATION
int counter=0,year=0,retval=0,count=0;
SizeVector Universe;
Universe.resize(7);
SizeVector *heretis;
char const NameFile[]="D:\\Friedout.csv";
heretis=&Universe;
for (count=0;count=6;count++)
{
Universe[count].R = double(0);
Universe[count].year = double(0);
}
count = 0;
for ( counter = 15000 ; counter = 100 ; counter-- )
{
if (counter==100||counter==2500||counter==5000||counter==7500||counter==10000||counter==12500||counter==15000)
{
Universe[count].year =double(counter);
Universe[count].R = double(counter*2);
count = count++;
if (retval ==-1)
{
break;
}
}
}
retval=write_to_file(6, Universe, NameFile);
//END OF CODE TO COMPUTE VALUES AND CALL FILE STORAGE ROUTINE
EINSTEIN.H HEADER FILE WITH ROUTINE TO PRODUCE OUTPUT CSV FILE
Code:
#ifndef EINSTEIN_H
#define EINSTEIN_H
#include <stdio.h>
#include <vector>
using namespace std;
struct SizeAll{
double year;
double R;
SizeAll() { year = 0; R = 0; }
};
typedef vector<SizeAll> SizeVector;
int write_to_file(int flag, SizeVector data, char const*fileName)
{
int Ecount = flag;
FILE* fp;
fp = fopen(fileName, "w");
if (fp == NULL) return -1;
while (Ecount-->-1) {
fprintf(fp, "%.1f,%.1f\n", data[Ecount].year, data[Ecount].R);
//check for errors writing to file
if (ferror(fp)) return -1;
}
fclose(fp);
return 0;
}
#endif
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Do you really mean this?
Code:
for ( counter = 15000 ; counter = 100 ; counter-- )
which sets counter to 100 every time it trys to go round the loop and always returns true so the loop never terminates!!
or do you actually want
Code:
for ( counter = 15000 ; counter >= 100 ; counter-- )
which checks that counter is >= 100?
-
Re: Trying to create a vector using a structure definition as the basis in VC++
I was trying to use the VB concept for "For Count = 1 to N" re-syntaxed as for (count = N; count =1; count --), to produce the same result but in reverse in terms of the values of "Count".
This seems to be where the code is probably locking up (which is one reason why I requested some expert advice regarding how to initiate tracing AFTER the "build" and select watch variables at that time as well).
Thank you once again "2kaud". Your consistent help in this topic is much appreciated. (The Boolean issue did occur to me this morning, but identifying the loop by learning how to turn on the trace seemed like a reasonable next step before I began to confirm the relevance of the construction of the loop's controlling symbols.)
Note: I still need to learn how to trace through the code while debugging and how to set watch variables AFTER the code has been built (so I can identify a specific loop in which the program becomes trapped and focus my attention on the relevant syntax affecting control over it on my own).
The code is still locking up even with this Boolean correction, so my inquiry regarding the trace option and watch variables remains relevant.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
I searched MSN forums. Found "watch" variable thread. Set breakpoint, and after building code, waited until breakpoint was hit, then set the watch variable. Problem proved to be due to the "while-do" loop in "Einstein.h" header file. Had to change logical test to "> 0". Now it runs perfectly. I still need to decide how to handle the return of a "-1" from file writing function in "Einstein.h" before I move on to actually perform any meaningful calculations. I presume VC++ has some built in single line of code that can be used to send a simple error message to the screen with an "OK" box selection, to preclude the need to design a new form just for an error message to react to the return of an error value ("-1") from the file writing routine? I'll initiate an on-line search for that facility and the related syntax.
Thanks again for all of your assistance!
-
Re: Trying to create a vector using a structure definition as the basis in VC++
You have the same problem here. This loop will never terminate!
Code:
for (count=0;count=6;count++) {
Universe[count].R = double(0);
Universe[count].year = double(0);
}
This code is not needed anyhow as Universe elements are being overwritten later. Also, there is no need to pass the number of elements to write_to_file. The vector method .size() will return the number of elements in the vector.
Why are you declaring heretis as a pointer to SizeVector????
My revised code based upon yours is
Code:
#include <stdio.h>
#include <vector>
using namespace std;
struct SizeAll{
double year;
double R;
SizeAll() { year = 0; R = 0; }
};
typedef vector<SizeAll> SizeVector;
int write_to_file(const SizeVector& data, char const *fileName)
{
FILE *fp;
size_t count = data.size();
if ((fp = fopen(fileName, "w")) == NULL) return -1;
while (count--) {
fprintf(fp, "%.1f,%.1f\n", data[count].year, data[count].R);
//check for errors writing to file
if (ferror(fp)) return -1;
}
fclose(fp);
return 0;
}
int main()
{
int retval,
count=0;
SizeVector Universe(7);
char const NameFile[] = "d:\\Friedout.csv";
for (int counter = 15000; counter >= 100; counter--) {
if (counter==100||counter==2500||counter==5000||counter==7500||counter==10000||counter==12500||counter==15000) {
Universe[count].year = double(counter);
Universe[count].R = double(counter*2);
count++;
}
}
retval = write_to_file(Universe, NameFile);
return 0;
}
This compiles and runs and produces the output
100.0,200.0
2500.0,5000.0
5000.0,10000.0
7500.0,15000.0
10000.0,20000.0
12500.0,25000.0
15000.0,30000.0
Note that in the function write_to_file you are passing the vector by value. This is very inefficent as every element of the vector is copied when the function is called. It is much better to pass the vector as a reference as per my code. I've use const as well as the function does not change the values of the vector.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Our posts crossed! I was composing mine when you sent yours!
The easiest way in Microsoft Windows to output an error message in a window on the screen is to use MessageBox. The MessageBox function creates, displays, and operates a message box. The message box contains an application-defined message and title, plus any combination of predefined icons and push buttons.
int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
For a simple error message, uType can be MB_OK and hWnd can be NULL. Thus an example would be
MessageBox(NULL, "Body of message", "Title", MB_OK);
You'll need to include windows.h for this (if it's not already included in stdafx.h). You said that you are using managed c++. I have no experience of managed c++ and implications of using MessageBox in that context.
Have more fun!
-
Re: Trying to create a vector using a structure definition as the basis in VC++
I found:
http://msdn.microsoft.com/en-us/libr...05(VS.85).aspx
in the Visual Programming forum sponsored by Microsoft.
It appears that the errors that may be induced by writing files are already handled by message boxes produced by the Windows API.
If I'm not in the midst of a function, and don't need to break out, which is the case now that I've modified the code to make it something I can now render more useful in a computational sense, wouldn't Windows handle any errors with its own, innately programmed requirement for a message box if an error occurs while writing a file, and leave me to simply ignore the error returned where the function to write the file is originally called? (I hate to pass the problem off to Windows, but perhaps that isn't a bad thing, given that it is the OS and the OS' job is writing files.) I'll simply leave a "comment" noting this decision at the point at which the error value would be returned just after the file writing function is called.
Quote:
=2kaud;2102979
The easiest way in Microsoft Windows to output an error message in a window on the screen is to use MessageBox. The MessageBox function creates, displays, and operates a message box. The message box contains an application-defined message and title, plus any combination of predefined icons and push buttons.
int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
For a simple error message, uType can be MB_OK and hWnd can be NULL. Thus an example would be
MessageBox(NULL, "Body of message", "Title", MB_OK);
You'll need to include windows.h for this (if it's not already included in stdafx.h). You said that you are using managed c++. I have no experience of managed c++ and implications of using MessageBox in that context.
Have more fun!
Thank you for your kind response.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
I substantially have my little program written, and it is generating a data file. I have to question the choice of variable types, because the value that is being tracked doesn't seem to change, although one would expect that it should, because a negative value is added to it in every step of the program. Have I somehow "desensitized" the result to the negative value being added because I'm storing the result in the wrong data type, and it simply doesn't have the precision required to reflect the small change in each step over thousands of steps? (I'm also wondering why I had to resort to the "pow(a,b)" approach to creating an exponent (i.e., "a * pow(10,b)" instead of "a * 10^b"). The code that performs the computation and calls the file generating routine follows, should anyone care to take a look.
Thank you.
Code:
//BEGINNING OF CODE WRITTEN TO IMPLEMENT COMPUTATION
//variable declaration and initiation.
int counter=0,year=0,retval=0,count=0,FileERR;
double delta_t = 1000000.;
double R_uni = 8.98*pow(10.,39.);
double delta_R = 0.;
double G = 6.67384*pow(10.,-11.);
double mass_uni = pow(10.,53.);
double rho;
//create a structured data variable
//containing radius and year for simulation,
//with years measured since "big bang"
SizeVector Universe;
Universe.resize(7);
char const NameFile[]="D:\\Friedout.csv";
for ( counter = 15000 ; counter >= 100 ; counter-- )
{
//Begin implementation of Gaussian approximation to expansion
//based upon cosmological constant as dominant energy form.
rho = 7/3*mass_uni/(4/3*3.1415*pow(R_uni,3));
delta_R = -2*R_uni*(sqrt(2*3.1415*G*rho/3))*delta_t;
R_uni = R_uni + delta_R;
//End Gaussian approximation to expansion
if (counter==100||counter==2500||counter==5000||counter==7500||counter==10000||counter==12500||counter==15000)
{
//This segment merely selects the values to be saved in the output file
//in a manner to be consistent with that used to produce spreadsheet
//graphs via an alternate model.
Universe[count].year =double(counter);
Universe[count].R = double(R_uni);
count = count++;
}
}
retval=write_to_file(count, Universe, NameFile);
if (retval ==-1)
{
}
//END OF CODE TO COMPUTE VALUES AND CALL FILE STORAGE ROUTINE
-
Re: Trying to create a vector using a structure definition as the basis in VC++
A couple of points.
1) c/c++ does not have an in-built 'power' operator. The '^' operator is actually the xor bitwise operator. Hence the pow function needs to be used.
2) numbers can be stated using the scientific 'e' format. So 8.98*pow(10.,39.) can be more easily expressed as 8.98e39.
3) The / used for division between integer numbers results in an integer. So from your code 4/3*3.1415 results in the value of 3.1415. Because 4 and 3 are integers and 4/3 results in 1 which is then promoted to a float so the result is 3.1415! What you should write is 4.0/3.0*3.1415 which gives the required result 4.18667.
Do you know what sort of figures you are expecting? These are what I got after making the above changes
100.0,8980000000000000600000000000000000000000.0
2500.0,8980000000000000600000000000000000000000.0
5000.0,8980000000000000600000000000000000000000.0
7500.0,8980000000000000600000000000000000000000.0
10000.0,8980000000000000600000000000000000000000.0
12500.0,8980000000000000600000000000000000000000.0
15000.0,8980000000000000600000000000000000000000.0
-
Re: Trying to create a vector using a structure definition as the basis in VC++
I've had a look at what you are trying to calculate and you have a problem using standard cmath library. The type double is represented as 8 bytes of memory - 64 bits - as per IEEE 754 standard. This is divided up as
52 bits for mantisa
11 bits exponent
1 bit mantisa sign
The problem you are encountering is with the 52 bits for the mantisa. This gives a maximum of 17 significant decimal digits of precision. In your case you start with 8.98e39 and then subtract 58891567.970510364 in the for loop. Unfortunately with only 52 bits for the mantisa, this has no effect on the stored number which stays the same! So in the next loop R-uni hasn't changed so at the end of the loop R-uni has the same value as at the start of the loop! The IEEE 754 standard can't give sufficient precision for your requirements as you are subtracting a relative small number from a large number. Effectively, you need 40 significant decimal digits of precision which the standard c++ library can't provide.
8980000000000000000000000000000000000000
0000000000000000000000000000000058891567
The coloured numbers are effectively the only ones stored. The other digits in the number are presumed to be always 0.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Thank you. That seems consistent with my prior impression.
I'll have to look into "long double" as an alternative.
I suspect that there may be an error in the formula.
I'll have to check it, or perhaps implement an alternative form.
Thank you.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
In c++, long double and double still take 8 bytes and there is no difference in terms of number of significent mantisa digits. Sorry, but using long double will make no difference.
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Quote:
Originally Posted by
Protocol
Thank you. That seems consistent with my prior impression.
I'll have to look into "long double" as an alternative.
If you're going to use numbers and math as you've shown, then you need to use a specialized library (GIMP is one such library) that does arbitrary math.
Otherwise, yes, you need to redo your formula(s). The forumulas you do in school or what you find in textbooks many times do not work correctly on a binary computing machine because of round-off error and numerical limits as to what can be represented. That's why many formulas have alternate forms just so they can be used on such machines.
Regards,
Paul McKenzie
-
Re: Trying to create a vector using a structure definition as the basis in VC++
Quote:
Originally Posted by Paul McKenzie
If you're going to use numbers and math as you've shown, then you need to use a specialized library (GIMP is one such library) that does arbitrary math.
Small typo there as the library is: GMP