string vector to string pointer manipulation

This is a discussion on string vector to string pointer manipulation within the C++ Programming forums, part of the General Programming Boards category; I'm trying to convert the list of strings into a single string in this form: "Pscript.dll

Thread: string vector to string pointer manipulation

QMS810.ppd

Thread: string vector to string pointer manipulation

Pscriptui.dll

Thread: string vector to string pointer manipulation

Pscriptui .hlp

Thread: string vector to string pointer manipulation

Pstest.txt

Thread: string vector to string pointer manipulation

Thread: string vector to string pointer manipulation

". However, I'm having ...

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

    string vector to string pointer manipulation

    I'm trying to convert the list of strings into a single string in this form: "Pscript.dll\0QMS810.ppd\0Pscriptui.dll\0Pscriptui .hlp\0Pstest.txt\0\0". However, I'm having some trouble adding the null characters properly. Here is my code and my problem is listed in the comments. Any suggestions?

    Code:
    // Process the vector into null terminated strings
    void func(const vector<wstring> pAdditionalFiles)
    {
    	LPTSTR pDependentFiles = NULL;
    
    	if(pAdditionalFiles.size())
    	{
    		// Allocate memory file for the pointers
    		pDependentFiles = new TCHAR[pAdditionalFiles.capacity()];
    		pDriverInfo->pDependentFiles = new TCHAR[pAdditionalFiles.capacity()];
    
    		_tcscpy(pDependentFiles, L"");
    
    		for(int i=0; i<pAdditionalFiles.size(); i++)
    		{
    			_tcscat(pDependentFiles, pAdditionalFiles[i].c_str());
    			_tcscat(pDependentFiles, L"\0");				// each filename needs to be null-terminated (get exception errors if I use '\0' as the source
    		}
    		_tcscat(pDependentFiles, L"\0");					// another null-terminator needed to end the list
    	}
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Each _tcscat will (I think) overwrite the ending \0 character with the start of the string that is being added to the end; and I believe it will write the \0 character itself (without you having to do the extra bit yourself). (At least it will if it behaves like the standard C strcat.)

    However, I don't know what you mean by this:
    I'm trying to convert the list of strings into a single string in this form: "Pscript.dll\0QMS810.ppd\0Pscriptui.dll\0Pscri ptui .hlp\0Pstest.txt\0\0".
    It is not possible to have such a string -- the first \0 ends the string, no questions asked. If you want to have a big char array that contains those characters in order, you can certainly do that, but you can't use the string tools to help you -- you'll have to keep track of where you are in the char array yourself.

  3. #3
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    I'm trying to manipulate the vector into pDependentFiles parameter in http://msdn.microsoft.com/en-us/libr...67(VS.85).aspx

  4. #4
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,554
    > pDependentFiles = new TCHAR[pAdditionalFiles.capacity()];
    But this needs to be the sum of all the (lengths+1) plus one for the final \0

    Then it would be something like
    Code:
    p = pDependentFiles;
    for(int i=0; i<pAdditionalFiles.size(); i++) {
      _tcscpy(p, pAdditionalFiles[i].c_str());
      p  += _tcslen( pAdditionalFiles[i].c_str() ) + 1;
    }
    *p = '\0';
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Okay. As mentioned there, that's not a string, that's a buffer (= char array). So treat it as an array -- you already declared it as such, so you won't have to change much. You will have to keep track of locations yourself. (In other words, after you write something, add its size +1 to array_index_where_I_am_writing_to and keep going.)

    Edit: Beaten with someone with actual code! Argh. But also: you have pDependentFiles by itself and as a member of a class -- be sure you're changing the one you want to change.
    Last edited by tabstop; 07-15-2008 at 01:00 PM.

  6. #6
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    I have pDependentFiles as a temporary buffer to manipulate the buffer, while I need to assign the result into pDriverInfo->pDependentFiles. I'm going to try some other method out before I come back here.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,319
    Why not do the concatenation with a wstring and then convert/copy to a character array at the end? If you use += on a wstring it will leave the embedded nulls.

  8. #8
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    I have managed to manipulate the buffer according to your suggestions. However, now I'm experiencing memory deallocation problem in the line highlighted in red. Is this b/c of the scope problems that I'm experiencing?
    Code:
    // Process the vector into null terminated strings
    	LPTSTR pDependentFiles = NULL;
    	LPTSTR p = pDependentFiles;
    	BOOL transferP = FALSE;
    
    	if(pAdditionalFiles.size())
    	{
    		// Allocate memory file for the pointers
    		pDependentFiles = new TCHAR[pAdditionalFiles.size() + pAdditionalFiles.capacity() + 1];
    		p = pDependentFiles;
    
    		for(int i=1; i<pAdditionalFiles.size(); i++)
    		{
    			_tcscpy(pDependentFiles, pAdditionalFiles[i].c_str());
    			pDependentFiles  += _tcslen( pAdditionalFiles[i].c_str() ) + 1;
    			*pDependentFiles = '\0';
    		}
    
    		pDependentFiles = new TCHAR;
    		pDependentFiles++;
    		*pDependentFiles = '\0';
    	}
    
    	pDriverInfo->pDependentFiles = p;
    
    	// Add Printer Driver and error check at the same time
    	if(!AddPrinterDriver(NULL, 6, (LPBYTE) pDriverInfo))
    	{
    		wcout << "Adding Printer Driver Unsuccessful: " << GetLastError() << endl;
    		delete[] pDependentFiles;
    		return FALSE;					// false means an error happened
    	}
    
    	// no errors occurred
    	delete[] pDependentFiles;               // runtime error here

  9. #9
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,554
    pDependentFiles = new TCHAR;
    pDependentFiles++;
    *pDependentFiles = '\0';
    So many mistakes!

    1. You lose the old pointer (that's a memory leak).
    2. You increment the pointer, then dereference (you've trashed someone elses memory).
    3. You use [ ] on the delete. a) it's not an array, b) it's not pointing to the start any more.

    What you wrote is nothing like what I posted.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  10. #10
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    After I use a really large sized array as the buffer rather than a dynamically-allocated pointer (I'm not very confident with dynamic memory allocation), I'm not experiencing the problems I've been experiencing anymore. Thank you all for your help.

  11. #11
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,554
    > pAdditionalFiles.size()
    Lemme guess, this is the number of strings, and not the total length of the strings.

    So when I said "this needs to be the sum of all the (lengths+1) plus one for the final \0", I didn't actually post how to do it (nor am I).
    But you NEED to do it if your dynamic allocation approach is to work.

    You do need to do this, you can't just run away and use a big array every time.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  12. #12
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    For this application, I think using a large enough array is going to work, as this is a very small application, with all the memory allocated to the scope of the application being deallocated after it's done executing.

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. Program using classes - keeps crashing
    By webren in forum C++ Programming
    Replies: 4
    Last Post: 09-16-2005, 03:58 PM
  3. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 08:32 AM
  4. Something is wrong with this menu...
    By DarkViper in forum Windows Programming
    Replies: 2
    Last Post: 12-14-2002, 10:06 PM
  5. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 02:23 PM