Solved

Elementary string functions in MS C2008

Posted on 2011-09-15
13
457 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
  • 6
  • 4
  • 3
13 Comments
 
LVL 30

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
 
LVL 30

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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 30

Accepted Solution

by:
Zoppo earned 500 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 30

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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
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 and use conditional statements in the C programming language.

758 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now