Question about fwrite under win32 platform

This is a discussion on Question about fwrite under win32 platform within the C Programming forums, part of the General Programming Boards category; I'm writing a win32 dialog application by using message crack macro, the problem is that I can't store the data ...

  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    42

    Question about fwrite under win32 platform

    I'm writing a win32 dialog application by using message crack macro, the problem is that I can't store the data into a target file correctly, but I use the same code in a console app, everything is ok. Here is a part of code about file writing.
    Code:
    void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
    {
    	
    	HWND add_hwnd;
    	int i,r1,r2,r3,r4,ret;
    	
    	LPTSTR t_isp = (LPTSTR)malloc(sizeof(LPTSTR));
    	LPTSTR t_uid = (LPTSTR)malloc(sizeof(LPTSTR));
    	LPTSTR t_pws = (LPTSTR)malloc(sizeof(LPTSTR));
    	LPTSTR t_num = (LPTSTR)malloc(sizeof(LPTSTR));
    	add_hwnd = GetDlgItem(hwnd,IDB_ADD);
    	
    	switch(id)
    	{
    		case IDCANCEL:
    			EndDialog(hwnd,id);
    			break;
    		case IDB_ADD:
    			i = 0;
    			if(GetDlgItemText(hwnd,IDE_ISP,t_isp,32) == 0 || 
    				GetDlgItemText(hwnd,IDE_ISP,t_isp,32) ==0 ||
    				GetDlgItemText(hwnd,IDE_PASSWORD,t_pws,32) ==0 ||
    				GetDlgItemText(hwnd,IDE_NUMBER,t_pws,32) ==0)
    			{
    				MessageBox(hwnd,"Some fields are empty!","Server Side",MB_OK);
    				break;
    			}
    			
    			if(count > 0 && count !=0 && i<SIZE)
    			{
    				GetDlgItemText(hwnd,IDE_ISP,t_isp,32);
    				r1 = GetLastError();
    				GetDlgItemText(hwnd,IDE_USERNAME,t_uid,32);
    				r2 = GetLastError();
    				GetDlgItemText(hwnd,IDE_PASSWORD,t_pws,32);
    				r3 = GetLastError();
    				GetDlgItemText(hwnd,IDE_NUMBER,t_num,32);
    				r4 = GetLastError();
    				if(r1 == 1400 || r2 == 1400 || r3 == 1400 || r4 == 1400)
    				{
    					MessageBox(hwnd,"GetLastError","Server Side",MB_OK);
    					break;
    				}
    				info[i].isp = t_isp;
    				info[i].uid = t_uid;
    				info[i].pws = t_pws;
    				info[i].num = t_num;
    				count = count - 1;
    				i = i + 1;
    				SetDlgItemText(hwnd,IDE_ISP,"");
    				SetDlgItemText(hwnd,IDE_USERNAME,"");
    				SetDlgItemText(hwnd,IDE_PASSWORD,"");
    				SetDlgItemText(hwnd,IDE_NUMBER,"");
    			}
    			else if(count == 0)
    			{
    				EnableWindow(add_hwnd,FALSE); 
    				MessageBox(hwnd,"The limitation of the record is arrived.","Server Side",MB_OK);
    			}
    			else
    			{
    				MessageBox(hwnd,"The limitation of the record is arrived","Server Side",MB_OK);
    			}
    			break;
    		case IDB_SAVE:
    			fp = fopen("data.dat","ab");
    			for(i = 0; i < SIZE; i++)
    				ret = fwrite(&info[i],sizeof(struct information),1,fp);
    			if(-1 != ret)
    				MessageBox(hwnd,"Save is ok!","Server Side",MB_OK);
    			else
    				MessageBox(hwnd,"Save is not completed!","Server Side",MB_OK);
    			fclose(fp);
    			break;
    	}
    }
    I set a break point into
    Code:
    ret = fwrite(&info[i],sizeof(struct information),1,fp);
    the content in info[i] is correct and return value is also correct. Why the content in the target file is incorrect?

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Ok, a few issues with your code that I'll work through one by one.
    Code:
    	LPTSTR t_isp = (LPTSTR)malloc(sizeof(LPTSTR));
    This is not how you use malloc. sizeof(LPTSTR) is 4 and this is not what you want.
    The correct way to use malloc is:
    Code:
    	ELEMENT* pElement = malloc(numberOfElements * sizeof(ELEMENT));
    - or -
    	ELEMENT* pElement = malloc(numberOfElements * sizeof(*pElement));
    so to allocate a string:
    Code:
            char* mystr = malloc(numberOfCharacters * sizeof(char));
    - or a TSTR (which is exactly the same thing in your program) -
            TCHAR* mystr = malloc(numberOfCharacters * sizeof(TCHAR));
    - or -
            LPTSTR mystr = malloc(numberOfCharacters * sizeof(TCHAR));
    Therefore, to allocate a string that can contain 32 characters (31 characters plus the nul terminator):
    Code:
             char* mystr = malloc(32 * sizeof(char));
    Alternatively, we can allocate the string on the stack. This has the added bonus that we don't have to check whether malloc failed:
    Code:
             char mystr[32];
    --
    Code:
            GetDlgItemText(hwnd,IDE_ISP,t_isp,32);
            r1 = GetLastError();
    GetLastError() will return a valid value after a function has failed. If a function has not failed, GetLastError() may return incorrect information. So this should be:
    Code:
            if (!GetDlgItemText(hwnd,IDE_ISP,t_isp,32))
                  r1 = GetLastError();
    --
    Code:
           if(r1 == 1400 || r2 == 1400 || r3 == 1400 || r4 == 1400)
    Rather than using "magic" numbers, it makes your code easier to read if you use constants so this becomes:
    Code:
           if(r1 == ERROR_INVALID_WINDOW_HANDLE || ...)
    --
    Finally, to the problem you outline with fwrite. The problem is that your structure contains pointers, in this case char pointers. As you know, a pointer is a number that points to information in memory. When you read back the structure the pointers will not be valid as the information in memory will have been lost.

    One solution is not to use pointers in your structure.
    Instead of:

    Code:
    struct mystruct {
          char* mystring;
    }
    you use a character array:
    Code:
    struct mystruct {
          char mystring[64];
    }

  3. #3
    Registered User
    Join Date
    Jun 2004
    Posts
    42
    To anonytmouse: thanks for your advice and answer! After I had posted this thread, I suddenly find the reason of the problem. As you've mentioned below, I just used character array instead of pointers, everything is ok.

    "GetLastError() will return a valid value after a function has failed. If a function has not failed, GetLastError() may return incorrect information. " ---- really? I never encounter this situation before, everytime I use GetLastError(), it always returns appropriate value that specify in MSDN.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. I need help to compile this code...
    By wise_ron in forum C Programming
    Replies: 17
    Last Post: 05-07-2006, 01:22 PM
  2. Win32 API or Win32 SDK?
    By jverkoey in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 07-20-2005, 04:26 PM
  3. Using standard C fscanf function with win32 save dialog
    By korbitz in forum Windows Programming
    Replies: 1
    Last Post: 04-08-2004, 04:31 PM
  4. fwrite question
    By fkheng in forum C Programming
    Replies: 3
    Last Post: 07-12-2003, 05:38 AM
  5. OLE Clipboard :: Win32 API vs. MFC
    By kuphryn in forum Windows Programming
    Replies: 3
    Last Post: 08-11-2002, 06:57 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21