2012-05-04 28 views
8

मैं fileName मेरी फाइल को बचाने के लिए प्राप्त करने के लिए इस कोड को लिखें:Win32 में GetSaveFileName के साथ फ़ाइल को कैसे सहेजना है?

#include "stdafx.h" 
#include <windows.h> 


int _tmain(int argc, _TCHAR* argv[]) 
{    
    OPENFILENAME ofn; 

    char szFileName[MAX_PATH] = ""; 

    ZeroMemory(&ofn, sizeof(ofn)); 

    ofn.lStructSize = sizeof(ofn); 
    ofn.hwndOwner = NULL; 
    ofn.lpstrFilter = (LPCWSTR)L"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; 
    ofn.lpstrFile = (LPWSTR)szFileName; 
    ofn.nMaxFile = MAX_PATH; 
    ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; 
    ofn.lpstrDefExt = (LPCWSTR)L"txt"; 

    GetSaveFileName(&ofn); 
    printf("the path is : %s\n", ofn.lpstrFile); 
    getchar(); 
    return 0; 
} 

लेकिन उत्पादन होता है:

the path is : H 

क्यों? क्या मुझसे कुछ गलत हो रही है ?

printf("the path is : %s\n", ofn.lpstrFile); 

printf की व्यापक चार संस्करण का उपयोग करना चाहिए:
मैं Windows 7.

+1

+1। –

उत्तर

8

इस लाइन पर विजुअल स्टूडियो 2008 का उपयोग कर रहा हूँ।

wprintf(L"the path is : %s\n", ofn.lpstrFile); 
+1

+1 आप जीतते हैं ... इस बार। :) –

+1

'lpstrFile' मान सहित शेष कोड के बाद से,' _TCHAR' पर आधारित है, आपको इसके बजाय '_tprintf' का उपयोग करना चाहिए:' _tprintf (_T ("पथ है:% s \ n"), ofn .lpstrFile); ' –

+2

-1 यह कोड अभी भी खतरनाक है क्योंकि बफर बहुत छोटा है। –

8

जड़ समस्या इन पंक्तियों में है:

char szFileName[MAX_PATH] = ""; 
... 
ofn.lpstrFile = (LPWSTR)szFileName; 
ofn.nMaxFile = MAX_PATH; 

यह MAX_PATH पात्रों में से एक बफर बनाता है, लेकिन यह GetSaveFileName समारोह है कि यह व्यापक पात्रों MAX_PATH के एक बफर है बताता है। जब कोई लंबा पथ नाम चुनता है तो यह क्रैश होने की संभावना है (या चुपचाप स्मृति को टंपल करें)।

देने वाला कलाकार है। कंपाइलर या पुस्तकालयों से झूठ मत बोलो। उन्हें यह पसंद नहीं है, और वे हमेशा अंत में अपना बदला ले लेंगे। उन पंक्तियों को इसके साथ बदलें:

WCHAR szFileName[MAX_PATH] = L""; 
... 
ofn.lpstrFile = szFileName; // no cast needed 
ofn.nMaxFile = MAX_PATH; 

अब चयनित फ़ाइल नाम विस्तृत वर्णों की एक स्ट्रिंग के रूप में वापस कर दिया जाएगा।

wprintf(L"the path is : %s\n", ofn.lpstrFile); // though I'd use szFileName at this point 

आप विस्तृत वर्णों के बजाय 8 बिट अक्षरों में स्ट्रिंग की जरूरत है, तो आप WideCharToMultiByte उपयोग कर सकते हैं: टोनी शेर का जवाब यह है कि कि आप की आवश्यकता wprintf बजाय printf का उपयोग करने के विस्तृत वर्णों के तार मुद्रित करने के लिए सही है । लेकिन मैं सामान्य रूप से विस्तृत चरित्र एपीआई के साथ रहूंगा।

तब तक कास्ट न करें जब तक आप यह नहीं जानते कि यह वास्तव में क्या करता है और यह आपके विशेष मामले में क्यों आवश्यक है।

-1

आप दोनों गलत हैं, यह एक साधारण सी सूचक/ढेर मुद्दा है।

// WRONG: 
char szFileName[MAX_PATH] = ""; 

यह सरणियों और संकेत confuses, आप ढेर पर एक सरणी की घोषणा है, लेकिन फिर डेटा अनुभाग में एक रिक्त स्ट्रिंग पर बात करने के लिए अपने स्मृति पता बदल दें। दूसरे शब्दों में, एक बफर ओवरफ्लो।

// RIGHT: 
char szFileName[MAX_PATH]; 
ZeroMemory(szFileName, MAX_PATH); 

यह स्टैक पर एक वर्ण सरणी घोषित करता है और सभी तत्वों को शून्य टर्मिनेटर में प्रारंभ करता है।

आशा है कि मदद करता है! पूर्ण उदाहरण और अच्छी तरह से तैयार प्रश्न के लिए

+0

सरणी प्रारंभकर्ताओं के दाहिने तरफ के शाब्दिक तारों का विशेष अर्थ है।कथन 'char szFileName [MAX_PATH] = "" '; * नहीं * एक सूचक बनाते हैं। यह 'szFileName [0] से '\ 0'' तक शुरू होता है, यानी शून्य टर्मिनेटर। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^