Strange strcpy problem
-
Hi. I've been quite a while out of C++, wasn't expert before either. But right now, I got a really strange problem with strcpy. Maybe somebody can help? : )
char cBuffer[256]; char cTemp[260]; //[some data is put into cBuffer here. cBuffer[0] = 'R'] char ch = cBuffer[0]; //So ch = 'R'. strcpy(cTemp, "R"); //This works. strcpy(cTemp, &ch); //This crashes.
So what should I do to put ch in cTemp??? Thank you in advance...-= E C H Y S T T A S =- The Greater Mind Balance Blending C++ with COM ^
-
Hi. I've been quite a while out of C++, wasn't expert before either. But right now, I got a really strange problem with strcpy. Maybe somebody can help? : )
char cBuffer[256]; char cTemp[260]; //[some data is put into cBuffer here. cBuffer[0] = 'R'] char ch = cBuffer[0]; //So ch = 'R'. strcpy(cTemp, "R"); //This works. strcpy(cTemp, &ch); //This crashes.
So what should I do to put ch in cTemp??? Thank you in advance...-= E C H Y S T T A S =- The Greater Mind Balance Blending C++ with COM ^
If you just want to copy the first character from
cBuffer
tocTemp
, then just do:cTemp[0] = cBuffer[0];
If you want to copy the entire string, then:
strcpy(cTemp,cBuffer);
From your example, remember that
ch
is only a single character. There is no space for a terminating'\0'
, so thestrcpy
is terminating on whatever random garbage follows thech
variable in the stack.
Software Zen:
delete this;
-
If you just want to copy the first character from
cBuffer
tocTemp
, then just do:cTemp[0] = cBuffer[0];
If you want to copy the entire string, then:
strcpy(cTemp,cBuffer);
From your example, remember that
ch
is only a single character. There is no space for a terminating'\0'
, so thestrcpy
is terminating on whatever random garbage follows thech
variable in the stack.
Software Zen:
delete this;
This is really weird. Watch this! I will give you the relevant pieces of code where cTemp and cBuffer are involved. This is really strange for me.
char cTemp[260]; //For temporary stringwork. char cTemp2[260]; //WTF??? char cBuffer[256]; //To read data from the file. //This is where I save something into cTemp. GetModuleFileName(0, cTemp, 249); //And this is where I save something into cBuffer. ReadFile(hFile, cBuffer, sizeof(char)*256, &dwNumRead, NULL); strcpy(cTemp2, cBuffer); //Crashes. strcpy(cTemp, cBuffer); //Also crashes.
HOWEVER!!! If I move the declaration for cTemp2 straight before the strcpy, it works!!! Like this:char cTemp2[260]; //WTF??? strcpy(cTemp2, cBuffer); //It works!!!. sTemp = cTemp2;
Why does it work !?!?!?!?!? What does anything have to do with where I declare the variable !??!!? I'll give you the full code, maybe there's something there I missed. There are some things here which you won't understand, but try not to get stuck in my local program logic. ASDANSIString is a class I made to work easier with strings. It's a wrapper over a char*, quite similar to the String class in .Net, it has lots of parsing methods incorporated in it.//Entry point. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { ASDANSIString sTemp; //For temporary stringwork. HANDLE hFile; //The file to read the window title from. MSG msgPump; //For dispatching OS messages. DWORD dwNumRead; //Number of bytes read from the file. long lCounter; char cTemp[260]; //For temporary stringwork. char cBuffer[256]; //To read data from the file. bReady = false; //Initializing. lTimerID = SetTimer(0, 0, 1000, (TIMERPROC)TimerProc); //Launching timer. //Retrieving the name of the window to close from the file.. GetModuleFileName(0, cTemp, 249); //Getting this module's path (the executable full name and path). sTemp = cTemp; //From now on using the ASDANSIString object to work with the path. sTemp = sTemp.SubStringA(0, sTemp.IndexOfRev("\\", 0)); //Copying only until the last backslash. sTemp += "\\Window Name.txt"; //Adding the name of the file to open. //Opening the file which contains the window name and reading the window name from it. hFile = CreateFile(sTemp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ReadFile(hFile, cBuffer, sizeof(char)*256, &dwNumRead, NULL); CloseHandle(hFile); char cTemp2[260]; //WTF???
-
This is really weird. Watch this! I will give you the relevant pieces of code where cTemp and cBuffer are involved. This is really strange for me.
char cTemp[260]; //For temporary stringwork. char cTemp2[260]; //WTF??? char cBuffer[256]; //To read data from the file. //This is where I save something into cTemp. GetModuleFileName(0, cTemp, 249); //And this is where I save something into cBuffer. ReadFile(hFile, cBuffer, sizeof(char)*256, &dwNumRead, NULL); strcpy(cTemp2, cBuffer); //Crashes. strcpy(cTemp, cBuffer); //Also crashes.
HOWEVER!!! If I move the declaration for cTemp2 straight before the strcpy, it works!!! Like this:char cTemp2[260]; //WTF??? strcpy(cTemp2, cBuffer); //It works!!!. sTemp = cTemp2;
Why does it work !?!?!?!?!? What does anything have to do with where I declare the variable !??!!? I'll give you the full code, maybe there's something there I missed. There are some things here which you won't understand, but try not to get stuck in my local program logic. ASDANSIString is a class I made to work easier with strings. It's a wrapper over a char*, quite similar to the String class in .Net, it has lots of parsing methods incorporated in it.//Entry point. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { ASDANSIString sTemp; //For temporary stringwork. HANDLE hFile; //The file to read the window title from. MSG msgPump; //For dispatching OS messages. DWORD dwNumRead; //Number of bytes read from the file. long lCounter; char cTemp[260]; //For temporary stringwork. char cBuffer[256]; //To read data from the file. bReady = false; //Initializing. lTimerID = SetTimer(0, 0, 1000, (TIMERPROC)TimerProc); //Launching timer. //Retrieving the name of the window to close from the file.. GetModuleFileName(0, cTemp, 249); //Getting this module's path (the executable full name and path). sTemp = cTemp; //From now on using the ASDANSIString object to work with the path. sTemp = sTemp.SubStringA(0, sTemp.IndexOfRev("\\", 0)); //Copying only until the last backslash. sTemp += "\\Window Name.txt"; //Adding the name of the file to open. //Opening the file which contains the window name and reading the window name from it. hFile = CreateFile(sTemp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ReadFile(hFile, cBuffer, sizeof(char)*256, &dwNumRead, NULL); CloseHandle(hFile); char cTemp2[260]; //WTF???
Remember that
ReadFile()
is not a CRT function - it makes no guarantees about nul-terminating the data it reads. Try this, it will probably work:char cBuffer[256] = { 0 }; // fill with nuls
Best wishes, Hans
[CodeProject Forum Guidelines] [How To Ask A Question] [My Articles]
-
Remember that
ReadFile()
is not a CRT function - it makes no guarantees about nul-terminating the data it reads. Try this, it will probably work:char cBuffer[256] = { 0 }; // fill with nuls
Best wishes, Hans
[CodeProject Forum Guidelines] [How To Ask A Question] [My Articles]
Indeed you are right. This solved all the strange problems I've been seeing, even though I still can't explain why (in the above post) declaring a char just before the strcpy did not crash. Well, too much to do today to busy myself with finding that out : (... guess it'll remain to be checked out in the future : D. Thank you very much. You're in the "Thanks To..." list : D. You'll soon see where (in what software... but don't worry, it's free, you made a good deed). EDIT: I've been thinking about this and maybe it's perhaps when I declare the char[] before reading from that file, the char is initialized by C++ while when declaring it after reading from the file it is not? Hmmmmmm. Doesn't make much sense. Hrmph... whatever...
-= E C H Y S T T A S =- The Greater Mind Balance Blending C++ with COM ^
-
This is really weird. Watch this! I will give you the relevant pieces of code where cTemp and cBuffer are involved. This is really strange for me.
char cTemp[260]; //For temporary stringwork. char cTemp2[260]; //WTF??? char cBuffer[256]; //To read data from the file. //This is where I save something into cTemp. GetModuleFileName(0, cTemp, 249); //And this is where I save something into cBuffer. ReadFile(hFile, cBuffer, sizeof(char)*256, &dwNumRead, NULL); strcpy(cTemp2, cBuffer); //Crashes. strcpy(cTemp, cBuffer); //Also crashes.
HOWEVER!!! If I move the declaration for cTemp2 straight before the strcpy, it works!!! Like this:char cTemp2[260]; //WTF??? strcpy(cTemp2, cBuffer); //It works!!!. sTemp = cTemp2;
Why does it work !?!?!?!?!? What does anything have to do with where I declare the variable !??!!? I'll give you the full code, maybe there's something there I missed. There are some things here which you won't understand, but try not to get stuck in my local program logic. ASDANSIString is a class I made to work easier with strings. It's a wrapper over a char*, quite similar to the String class in .Net, it has lots of parsing methods incorporated in it.//Entry point. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { ASDANSIString sTemp; //For temporary stringwork. HANDLE hFile; //The file to read the window title from. MSG msgPump; //For dispatching OS messages. DWORD dwNumRead; //Number of bytes read from the file. long lCounter; char cTemp[260]; //For temporary stringwork. char cBuffer[256]; //To read data from the file. bReady = false; //Initializing. lTimerID = SetTimer(0, 0, 1000, (TIMERPROC)TimerProc); //Launching timer. //Retrieving the name of the window to close from the file.. GetModuleFileName(0, cTemp, 249); //Getting this module's path (the executable full name and path). sTemp = cTemp; //From now on using the ASDANSIString object to work with the path. sTemp = sTemp.SubStringA(0, sTemp.IndexOfRev("\\", 0)); //Copying only until the last backslash. sTemp += "\\Window Name.txt"; //Adding the name of the file to open. //Opening the file which contains the window name and reading the window name from it. hFile = CreateFile(sTemp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ReadFile(hFile, cBuffer, sizeof(char)*256, &dwNumRead, NULL); CloseHandle(hFile); char cTemp2[260]; //WTF???
Axonn Echysttas wrote:
ReadFile(hFile, cBuffer, sizeof(char)*256, &dwNumRead, NULL);
Try this:
ReadFile(hFile, cBuffer, sizeof(char)*256, &dwNumRead, NULL);
cBuffer[dwNumRead] = '\0';
strcpy(cTemp2,cBuffer);As mentioned elsewhere,
ReadFile
simply reads bytes from a file. It does not guarantee that a terminator is placed in the destination. The line I've added places a'\0'
terminator after the data read, so that it's safe later on to perform thestrcpy
.
Software Zen:
delete this;
-
Hi. I've been quite a while out of C++, wasn't expert before either. But right now, I got a really strange problem with strcpy. Maybe somebody can help? : )
char cBuffer[256]; char cTemp[260]; //[some data is put into cBuffer here. cBuffer[0] = 'R'] char ch = cBuffer[0]; //So ch = 'R'. strcpy(cTemp, "R"); //This works. strcpy(cTemp, &ch); //This crashes.
So what should I do to put ch in cTemp??? Thank you in advance...-= E C H Y S T T A S =- The Greater Mind Balance Blending C++ with COM ^
While a char* is often called a "string" in C, they are not the same thing. A "string" is a specially-formatted array of chars. Taking the address of one single char doesn't make it a string.
--Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ Dunder-Mifflin, this is Pam.