Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 492
  • Last Modified:

Elementary string functions in MS C2008

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
dvplayltd
Asked:
dvplayltd
  • 6
  • 4
  • 3
1 Solution
 
ZoppoCommented:
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
 
tampnicCommented:
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
 
tampnicCommented:
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
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
ZoppoCommented:
Hm - sorry, but I mentioned this already ...
0
 
tampnicCommented:
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
 
dvplayltdAuthor Commented:
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
 
ZoppoCommented:
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
 
dvplayltdAuthor Commented:
10x - now is working!!! Aaa. 1 hour to join 3 varables, this is new record for slow writting of software ! AAAAAA!
0
 
tampnicCommented:
What was the run-time error please?

Cheers,
  Chris
0
 
tampnicCommented:
No matter - I see you accepted Zoppo's solution. I really should refresh my browser before making posts :-)

Cheers,
 Chris
0
 
ZoppoCommented:
: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
 
dvplayltdAuthor Commented:
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
 
tampnicCommented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

  • 6
  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now