Thread: string manipulation problems

  1. #1
    Registered User
    Join Date
    Jul 2004
    Posts
    222

    string manipulation problems

    I'm having problems with this line of the code:

    Code:
    txtCompareResults = lstrcmp((LPCWSTR) argv[1], TEXT("-name"));
    My problem is that when argv[1] is "-name", lstrcmp doesn't return a value of 0, which means that the texts are identical. Does anyone know why that may be the case?

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    how are you declaring main?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    Code:
    void main(int argc, char* argv[])
    Could the void keyword be why?

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    um, no. but argv is an array of char - not wchar_t. you'll need to either declare a wide-character main (eg: int wmain( int, wchar_t**)) or convert (not cast) the command line parameters to wchar_t strings.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    Is there a standard function/API method in Windows where I can perform the conversion or do I have to implement it myself?

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    There's MultiByteToWideChar, but what for? The source string is narrow, you're comparing against a literal that contains nothing but basic characters, so just use narrow strings and strcmp. (Or lstrcmpA, if you don't want the CRT dependency.)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    Thanks for the heads up on strcmp.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    There apparent appears a case where I would have to carry out the conversion. Here is some code example:

    Code:
            // Convert the ANSI argument for the pDriverName
    	// to UNICODE
            char* pDriverName = "Some Name";
    	LPWSTR pDriverNameW = NULL;
    	pDriverNameW = (LPWSTR) malloc(sizeof(pDriverName));
    	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
    		pDriverName, 
    		sizeof(pDriverName),
    		pDriverNameW,
    		sizeof(pDriverName)
    		);
    	wcout << "pDriverNameW = " << pDriverNameW << endl;
    I have tried to fiddle with the size parameters of the function, but I can never seem to convert properly. It just converts the first string: "Some♠". Does anyone know about what's going on with the MultiBytetoWideChar function call (I found that the problem is how I called this function)? Thanks.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The problem is that sizeof(pDriverName) gives you the number of bytes in the platform's pointer, not how big the string is.

    What you should do is this:
    Code:
    const char *pDriverName = "Some Name"; // Never assign string literals to non-const pointers.
    int size = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pDriverName, -1, 0, 0);
    if(size == 0) {
      // handle error - this shouldn't ever happen
    }
    WCHAR *pDriverNameW = new WCHAR[size]; // or (WCHAR*)malloc(size * sizeof(WCHAR) for C.
    // if using malloc, handle allocation error
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pDriverName, -1,
      pDriverNameW, size);
    
    // ...
    
    delete[] pDriverNameW;
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    Thanks for the tip. Haven't noticed this reply until now. And it worked quite nicely. Do a lot of win32 functions work like this (first function call to know how much memory to allocate and then perform the actual operation on the second try)?

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Not all of them, but some do. Be sure to read the manual.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    I have been trying a similar string manipulation code below, but I have been getting an error with my instantiation of flist with the error
    Code:
    1>e:\test\installer\installer.cpp(105) : error C2057: expected constant expression
    1>e:\test\installer\installer.cpp(105) : error C2466: cannot allocate an array of constant size 0
    1>e:\test\installer\installer.cpp(105) : error C2075: 'flist' : array initialization needs curly braces
    Code:
    int flist_num = argc - INSTARGC;
    if (flist_num > 0)
    {
    	wstring flist[flist_num] = 0;
    	for (DWORD i = 0; i < flist_num; i++)
    	{
    		size = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, argv[i+INSTARGC], -1, 0, 0);
    		if(size==0)
    		{
    			wcout << "Error occurred when trying to allocate memory for conversion"
    				<< endl;
    		}
    		tempPrinterName = new WCHAR[size];
    		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, argv[i+INSTARGC], 
    						-1, tempPrinterName, size);
    		flist[i] = wstring(tempPrinterName);
    		delete[] tempPrinterName;
    		wcout << flist[i] << endl;
    		}
    }
    My trouble is that I don't really know what would be in the contents of flist until I have finished processing the arguments passed in the main function. Would I need to have some type of variable arrays to do this?

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    wstring flist[flist_num] = 0;

    You cannot dynamically allocate an array this way in C++. It must be a size that is known at compile time and obviously it isn't, so you get an error.
    Another way to do it is to make it a std::vector<wchar_t> and call .resize().
    Remember that Win32 API takes C-style strings, not C++ strings, so it must be wchar_t, NOT wstring.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    Thanks for your help regarding using vectors to get around the problem. I have one more question regarding another type of manipulation:

    Code:
    #include <windows.h>
    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
    	WCHAR resultant[64];
    	const WCHAR* someName = L"Black Panther";
    
    	resultant = someName;
    
    	system("pause");
    
    	return 0;
    }
    Supposedly I tried to do something like above in a bigger project, but I'm getting an error like
    Code:
    1>e:\test\copydriverfiles\copydriverfiles.cpp(11) : error C2440: '=' : cannot convert from 'const WCHAR *' to 'WCHAR [64]'
    I'm trying to copy someName into resultant, or at least the contents to be copied. Is there anything seriously wrong with what I'm trying to do?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Inheritance Hierarchy for a Package class
    By twickre in forum C++ Programming
    Replies: 7
    Last Post: 12-08-2007, 04:13 PM
  2. Calculator + LinkedList
    By maro009 in forum C++ Programming
    Replies: 20
    Last Post: 05-17-2005, 12:56 PM
  3. io stream and string class problems
    By quizteamer in forum C++ Programming
    Replies: 2
    Last Post: 04-25-2005, 12:07 AM
  4. Something is wrong with this menu...
    By DarkViper in forum Windows Programming
    Replies: 2
    Last Post: 12-14-2002, 11:06 PM