Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Elementary string functions in MS C2008

Posted on 2011-09-15
13
Medium Priority
?
489 Views
Last Modified: 2012-05-12
I’m programmer with 10+ years in industry, but totally new to MS C 2008 and I need help. Look that works with string in C is TOTALLY different than to Vb6 or C# :-( :-( :-(. Please helppppppppp.

Look my code and read the comments,  the question is on it.
BSTR CCPlayCtrl::sDecoderInfo(long lCard)
{
      CString strResult;LPCTSTR strVersion;
      int iNumDecoders = 0; long lRev = 0;

   hDecoder=hDec[lCard];

   if (hDecoder != INVALID_STRADIS_HANDLE) return strResult.AllocSysString();


      lRev = Stradis_GetRevision();
        iNumDecoders = Stradis_GetNumberOfDecoders();
        if (StradisDecoder_IsVersion2(hDecoder)) strVersion="2"; // how to put value "2" in  LPCTSTR ??? Or may be I need other type?
        if (StradisDecoder_IsVersion3(hDecoder)) strVersion="3";
        if (StradisDecoder_IsVersion4(hDecoder)) strVersion="4";

    return lRev + "," + iNumDecoders + "," + strVersion // how to join all 3 values in a one string and return it to BSTR ??? if I join it to CString will be fine
//      return strResult.AllocSysString(); this is OK like return type
}

Please, give me working code, not links to pages where is explain how C works with strings ¿. You can replace STradis function with constants, for example like
if (true) strVersion="3";
0
Comment
Question by:dvplayltd
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 3
13 Comments
 
LVL 31

Expert Comment

by:Zoppo
ID: 36541796
Hi dvplayltd,

IMO you don't need LPCTSTR at all - and you cannot simply put a string into a LPCTSTR since a LPCTSTR is a TCHAR* so it's just a pointer to a list of characters which have to be allocated before.

So, use CString for both the strVersion and strResult and use CString::Format to join the values i.e. like this:
BSTR CCPlayCtrl::sDecoderInfo(long lCard)
{
   CString strResult, strVersion;
   int iNumDecoders = 0; long lRev = 0;

   hDecoder=hDec[lCard];

   if (hDecoder != INVALID_STRADIS_HANDLE) return strResult.AllocSysString();


   lRev = Stradis_GetRevision();
   iNumDecoders = Stradis_GetNumberOfDecoders();
   if (StradisDecoder_IsVersion2(hDecoder)) strVersion="2";
   if (StradisDecoder_IsVersion3(hDecoder)) strVersion="3";
   if (StradisDecoder_IsVersion4(hDecoder)) strVersion="4";

   strResult.Format( "%d,%d,%s", lRev, iNumDecoders, strVersion );
   return strResult.AllocSysString(); this is OK like return type
}

Open in new window

Hope that helps,

ZOPPO
0
 
LVL 7

Expert Comment

by:tampnic
ID: 36541797
With regards to getting the value "2" into strVersion ...

strVersion is a  LPCTSTR (long pointer to constant text string). You can't modify a constant text string so it should be a LPTSTR (long pointer to text string).

Secondly, you have not allocated any memory for the string so strVersion is pointing to an empty buffer. If its only going to have one character in the string, allocate two bytes when its declared using TCHAR strVersion[2]. strVersion now points to a buffer with two bytes allocated, one for the character and one for the null-terminator which C strings require. This is called static memory allocation - dynamic memory aloocation is possible too but I'll try and keep this short!

To join up different types of variable into a string use CString::Format(). It uses the standard sprintf formatting codes which you can look up at a later date.

I attach working code ...

 
Look my code and read the comments,  the question is on it.
BSTR CCPlayCtrl::sDecoderInfo(long lCard) 
{
      CString strResult;
      TCHAR strVersion[2];
      int iNumDecoders = 0; long lRev = 0;

   hDecoder=hDec[lCard];

   if (hDecoder != INVALID_STRADIS_HANDLE) return strResult.AllocSysString();


      lRev = Stradis_GetRevision();
        iNumDecoders = Stradis_GetNumberOfDecoders();
        if (StradisDecoder_IsVersion2(hDecoder)) _tcsncpy(strVersion, _T("2"),_countof(strVersion)); // how to put value "2" in  LPCTSTR ??? Or may be I need other type?
        if (StradisDecoder_IsVersion3(hDecoder)) _tcsncpy(strVersion, _T("3"),_countof(strVersion));
        if (StradisDecoder_IsVersion4(hDecoder)) _tcsncpy(strVersion, _T("4"),_countof(strVersion));

    strResult.Format(_T("%l,%d,%s"),lRev,iNumDecoders,strVersion );   
    //return lRev + "," + iNumDecoders + "," + strVersion // how to join all 3 values in a one string and return it to BSTR ??? if I join it to CString will be fine
      return strResult.AllocSysString(); this is OK like return type
}

Open in new window


Cheers,
  Chris
0
 
LVL 7

Expert Comment

by:tampnic
ID: 36541865
If you want to get away from the worry of memory allocation for strVersion, declare it as a CString. i.e.
CString strVersion. You can then simply state strVersion = _T("2"); instead of using the _tcsncpy() function I used in the code snippet previously. The CString class takes care of memory allocation for you.

Cheers,
   Chris
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 31

Expert Comment

by:Zoppo
ID: 36541872
Hm - sorry, but I mentioned this already ...
0
 
LVL 7

Expert Comment

by:tampnic
ID: 36541875
I just noticed you got in half a minute before me Zoppo :-) My code is slightly more portable as I've used the text macros in case the questioner is working on a Unicode project.

Cheers,
  Chris
0
 

Author Comment

by:dvplayltd
ID: 36542004
To tampnic

I'm sorry to inform you that both codes make error. For tampnic it is on row

for values return from functions

lRev=359; iNumDecoders=1;strVersion="4"

  strResult.Format(_T("%l,%d,%s"),lRev,iNumDecoders,strVersion);  

generate error in run time.

To Zoppo

You code generate error in compile
Error      6      error C2664: 'void ATL::CStringT<BaseType,StringTraits>::Format(const wchar_t *,...)' : cannot convert parameter 1 from 'const char [9]' to 'const wchar_t *'      d:\aadinserter\stardisocx\cplay\cplayctl.cpp      735      CPlay


Look that string work in C in very hard . For me people doing User Interface on C are CRAZY ... :-)
0
 
LVL 31

Accepted Solution

by:
Zoppo earned 2000 total points
ID: 36542013
Sorry, I thought you're not use UNICODE because you haven't use _T-macro. This should compile better:
BSTR CCPlayCtrl::sDecoderInfo(long lCard)
{
   CString strResult, strVersion;
   int iNumDecoders = 0; long lRev = 0;

   hDecoder=hDec[lCard];

   if (hDecoder != INVALID_STRADIS_HANDLE) return strResult.AllocSysString();


   lRev = Stradis_GetRevision();
   iNumDecoders = Stradis_GetNumberOfDecoders();
   if (StradisDecoder_IsVersion2(hDecoder)) strVersion=_T( "2" );
   if (StradisDecoder_IsVersion3(hDecoder)) strVersion=_T( "3" );
   if (StradisDecoder_IsVersion4(hDecoder)) strVersion=_T( "4" );

   strResult.Format( _T( "%d,%d,%s" ), lRev, iNumDecoders, strVersion );
   return strResult.AllocSysString(); this is OK like return type
}

Open in new window

And, BTW, this isn't really string handling in C, it's C++ with ATL/MFC's CString class which is much easier than string handling in pure C :o)

ZOPPO
0
 

Author Closing Comment

by:dvplayltd
ID: 36542035
10x - now is working!!! Aaa. 1 hour to join 3 varables, this is new record for slow writting of software ! AAAAAA!
0
 
LVL 7

Expert Comment

by:tampnic
ID: 36542042
What was the run-time error please?

Cheers,
  Chris
0
 
LVL 7

Expert Comment

by:tampnic
ID: 36542057
No matter - I see you accepted Zoppo's solution. I really should refresh my browser before making posts :-)

Cheers,
 Chris
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 36542074
:o)

BTW, I think the problem is the '%l' - AFAIK '%l' is not a valid type field in a format string. To print out 'long' IMO it should be '%ld' (or '%lu' for 'unsigned long') instead.

I had the luck 'int' and 'long' have same size in Visual C++, so '%d' works the same as '%ld'.

ZOPPO
0
 

Author Comment

by:dvplayltd
ID: 36542089
To tampnic

I do not get message with error text, it just exit as it is ActiveX OCX and just exit. Thank you for your time.
0
 
LVL 7

Expert Comment

by:tampnic
ID: 36542411
You hit the nail on the head Zoppo - I typed %l instead of %ld which was what I meant. Kudos to you.

Cheers,
  Chris
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

597 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question