|
I'm not quite sure why you asked *almost* the same question 20 minutes later...
LPCSTR <-- narrow
LPCWSTR <-- wide
LPCTSTR <-- depends on UNICODE (or _UNICODE, I forget which)
Iain.
|
|
|
|
|
Good reply, Iain!
regards,
George
|
|
|
|
|
Hi Iain,
A further question,
why the statement has warning message when UNICODE is defined (you can find it from my sample in question)?
WCHAR* p = _T("hello");
warning C4133: 'initializing' : incompatible types - from 'char [6]' to 'WCHAR *'
regards,
George
|
|
|
|
|
No idea, I don't use WCHAR. You'd have to look at the headers to see what's going on.
But I'd change the _T("Hello") to L"Hello". If *that* works, then _T is converting to ascii, and you haven't defined _UNICODE or UNICODE (I can never remember which is which, but one is for C, and one for Win32).
The reason you bother with _T is so that the code will be either ascii or unicode, depending on the defines. In which case, you should use TCHAR, as this varies similarly. If you're hard wiring for unicode, then you can write:
wchar_t *p = L"Hello";
instead.
You had a similar issue in another question to to with LPSTR/LPTSTR/LPWSTR. You need to make up your mind whether you're being ascii, dependent on defines, or full on unicode.
This mixing of hard wired and dependent-on-defines code is going to give you errors in both directions...
Iain
|
|
|
|
|
Thanks Iain,
Iain Clarke wrote: one is for C, and one for Win32
What do you mean one is for C and one for Win32? You mean _UNICODE for C? UNICODE for Win32? Could you provide more information please?
regards,
George
|
|
|
|
|
When I said I couldn't remember which one is which, I meant it. It's not all that hard to search in MSDN for the definitions, or use Visual C++ to search for the #ifdef's in the header files to see where they crop up. Basically, if I need either of them, I need both.
It's one thing for us to be helpful, but you gotta do *some* of the work yourself!
Iain.
|
|
|
|
|
Thanks for your advice, Iain!
regards,
George
|
|
|
|
|
Hi All,
I am developing a MFC ActiveX Control. In that I have exposed one method to the automation client.This method has four argument. First will be the object of class CMyItem and second will be the object of CMyObj class.
<br />
LONG CMyCtrl::ExecuteRequest(IDispatch* myItem,IDispatch* myObj, LPCTSTR str1,LPCTSTR extraInfo)<br />
{<br />
return 0;<br />
}<br />
Now I want to get back the object from IDispatch.
i.e.
<br />
CMyObj m_obj; <br />
CMyItem m_item;<br />
<br />
m_item = myItem ;
myobj = myObj ;
<br />
myobj.Dosomething();<br />
<br />
But the compiler is giving an error saying that cant convert from IDispatch to class object.
Any Idea how can I get cast the object from IDispatch to class
Thanks,
Micky
|
|
|
|
|
If the objects are derived from IDispatch, you should be able to downcast the
passed IDispatch pointers. Note that you can't directly cast a pointer to an object
like you've shown.
CMyObj *m_obj;
CMyItem *m_item;
m_item = dynamic_cast<CMyItem *>(myItem) ;
myobj = dynamic_cast<CMyObj *>(myObj) ;
...
myobj->Dosomething(); Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I am having trouble gettting this program to compile and I am not sure why. It keeps telling me that every time I try to declare a new instance of student (example; student st) it says I am missing parameters for it. Maybe someone can offer a little assistance. The program is devised into 3 parts; main(), class student.cpp, header student.h
//student.cpp
#include <iostream>
#include <string>
#include "student.h"
using namespace std;
class student
{
public:
void setInfo(string fname, string lname, int grade); //funtion to assign values to an instance of student
string getName(); //function to retreive the value of first & last name
int getGrade(); //function to retrieve the numerical value of the test score
student(); //default constructor
student(string first, string last, int gradeScore)
string first;
string last;
int gradeScore;
}
//Header file for class student
#ifndef H_student
#define H_student
#include <string>
#include <iostream>
using namespace std;
student::student(string first, string last, int gradeScore)
{
first = fname;
last = lname;
gradeScore = grade;
}
student::student()
{
first = " ";
last = " ";
grade = 0;
}
void student::setInfo(string fname, string lname, int grade)
{
first = fname;
last = lname;
gradeScore = grade;
}
string student::getName()
{
fname = first;
lname = last;
return (first, last);
}
int student::getGrade()
{
grade = gradeScore;
return gradeScore;
}
private:
int gradeScore;
string first;
string last;
#endif
//main()
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include "student.h"
using namespace std;
vector<student> studentList;
int getAverage(vector<student> studentList);
void displayAverage(int avg);
void displayUnderAvg(vector<student> studentList, int avg)
void displayTopStudent(vector<student> studentList);
int main()
{
string firstName;
string lastName;
int score;
int i;
int size;
int average;
student sTemp;
cout << "How many students do you want to enter: ";
cin >> size;
cout << endl << "Please enter the first and last name of the student"
<< endl << "followed by their numerical test grade from 0-100."
<< endl << "(example: David Miotke 98);
for (i=0; i < (size-1); i++)
{
cout << "Enter info for student #" << (i+1) << ": ";
cin >> firstName >> lastName >> score;
sTemp.setInfo(firstName, lastName, score);
studentList.push_back(sTemp);
}
average = getAverage(vector<student> studentList);
displayAverage(average);
displayUnderAvg(vector<student> studentList, average);
displayTopStudent(vector<student> studentList);
return 1
}
int getAverage(vector<student> studentList)
{
unsigned int count;
int sAverage;
int total = 0;
student stud;
for (count = 0; count < studentList.size(); count++)
{
stud.setInfo(studentList[count]);
total = (total + stud.getGrade());
}
sAverage = (total / studentList.size());
return sAverage;
}
void displayAverage(int avg)
{
cout << "The average test score is " << avg << "%" << endl;
}
void displayUnderAvg(vector<student> studentList, int avg)
{
unsigned int count;
student stud;
for (count = 0; count < studentList.size(); count++)
{
stud.setInfo(studentList[count]);
if (stud.getGrade() < avg)
cout << "The following students have scored under the test average:" << endl;
<< stud.getName() << " (" << stud.getGrade() << "%)" << endl;
}
}
void displayTopStudent(vector<student> studentList)
{
unsigned int count;
int top = 0;
student stud;
student st;
for (count = 0; count < studentList.size(); count++)
{
stud.setInfo(studentList[count]);
if (stud.getGrade() > top)
{
top = stud.getGrade();
st.setInfo(studentList[count];
}
}
cout << "The top scoring student is..." << endl
<< st.getName() << " (" << top << "%)" << endl;
}
|
|
|
|
|
1) You lost some "<"s and ">"s in your post. Could you modify it with the formatting buttons below?
2) Could you make your question short instead of posting the entire code?! Thanks!
Maxwell Chen
|
|
|
|
|
Please post only the relevant code snippet (e.g., a dozen lines or so), and utilize the <pre> tags.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
There are a number of problems:
1. The class definition needs to go in file student.h, the implementation details go in student.cpp
2. Missing semi-colon after the second constructor in the class definition
3. Missing semi-colon after the closing brace in the class definition
4. When declaring a vector you need to specify the type that is contained, i.e.
vector<Student> StudendList
I think that this is likely just the problem with the angle brackets in post
5. The comma operator does not do what you think it does in
string student::getName()
{
return (first, last);
}
It evaluates the first expression (which doesn't do anything) and then returns the second expression. So this expression merely returns the last name. Assuming that you wanted to return the full name I expect that you want something like:
string student::getName()
{
return std::string(first).append(",").append(last);
}
There are other errors (e.g. misnamed and missing variables) but I'm sure you'll be able to find them
Might I suggest that you try a more incremental approach to producing code. Write a small bit of code, get it to compile and test it. Once that works add some more functionality and go through the cycle again. Even the most experienced programmers work this way
-- modified at 11:47 Monday 20th August, 2007
Graham
My signature is not black, just a very, very dark blue
|
|
|
|
|
Hello everyone,
I think for any platform (no matter whether on the platform, multibyte character or wide character is used as default encoding approach, for example, on Windows CE wide character is used as default encoding approach, i.e. UNICODE or _UNICODE is defined, and on Windows desktop platform, multibyte character is used as default), I could achieve the same function for any platform by either,
1. invoking fopen and pass file name encoded as multibyte character, no matter whether multibyte character or wide character is used as default encoding approach;
2. invoking wfopen and pass file name encoded as wide character, no matter whether multibyte character or wide character is used as default encoding approach.
thanks in advance,
George
|
|
|
|
|
So what's your question/problem?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Thanks David,
My question is, I want to know whether my understanding is correct for the two points,
(for any platform (no matter whether on the platform, multibyte character or wide character is used as default encoding approach, for example, on Windows CE wide character is used as default encoding approach, i.e. UNICODE or _UNICODE is defined, and on Windows desktop platform, multibyte character is used as default), I could achieve the same function for any platform by either)
--------------------
1. invoking fopen and pass file name encoded as multibyte character, no matter whether multibyte character or wide character is used as default encoding approach;
2. invoking wfopen and pass file name encoded as wide character, no matter whether multibyte character or wide character is used as default encoding approach.
--------------------
regards,
George
|
|
|
|
|
Why not just use _tfopen() and not have to worry about it?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Thanks David,
I just want to make a study and research and I want to use the preferred function independent of whether UNICODE or _UNICODE is defined.
When UNICODE or _UNICODE is defined, _tfopen() will be defined to wfopen, and when UNICODE and _UNICODE are not defined, _tfopen() will be defined to fopen.
My purpose is, I want to use fopen and wfopen independent of whether UNICODE or _UNICODE is defined. For example, when UNICODE is defined, I want to use fopen.
Could you read and comment my original question to see whether my understanding is correct?
regards,
George
|
|
|
|
|
George_George wrote: ...I want to use the preferred function independent of whether UNICODE or _UNICODE is defined.
Hence my suggestion to use _tfopen() .
George_George wrote: For example, when UNICODE is defined, I want to use fopen.
Which is exactly what happens. Check the preprocessor output, and you'll notice that fopen() is being used.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Thanks David,
How to check preprocessor output in Visual Studio 2003?
regards,
George
|
|
|
|
|
George_George wrote: How to check preprocessor output in Visual Studio 2003?
See here.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Yes, your understanding is correct. However, these things are taken care by "Using Generic-Text Mappings". For example, if you use _tfopen (Generic-text routine name) and if SBCS (_UNICODE & MBCS Not Defined) then it will convert as fopen, if MBCS defined - fopen and if UNICODE defined - _wfopen.
Please refer http://msdn2.microsoft.com/en-us/library/7dzey6h6(VS.80).aspx[^] for more information.
Regards,
Paresh.
|
|
|
|
|
Thanks Paresh,
I want to confirm that, for any Windows platform, no matter whether UNICODE or _UNICODE is defined, we could invoke fopen and wfopen freely. Right?
For example, when UNICODE or _UNICODE is defined, we could still use fopen and pass multibyte encoded characters. Right?
regards,
George
|
|
|
|
|
FILE *fopen( const char *filename, const char *mode );<br />
FILE *_wfopen( const wchar_t *filename, const wchar_t *mode );
The fopen function opens the file specified by filename. _wfopen is a wide-character version of fopen; the arguments to _wfopen are wide-character strings. _wfopen and fopen behave identically otherwise.
If the symbol _UNICODE is defined for your program, parameter "filename" is of type pointer to wchar_t, a 16-bit character type; otherwise, it is of type pointer to char, the normal 8-bit character type.
Please refer below websites for more information,
http://www.i18nguy.com/unicode/c-unicode.html[^]
http://msdn2.microsoft.com/en-us/library/yeby3zcb(VS.80).aspx[^] - Look at "Generic-Text Routine Mappings".
Regards,
Paresh.
|
|
|
|
|
Thanks Paresh,
I think I can use fopen even if I defined UNICODE, and pass parameter in multibyte character, right?
regards,
George
|
|
|
|
|