2013-10-23 2 views
2

Qt는 윈도우 ' "CreateDirectory"반환 -1 오류와 디렉토리 만들기 ./dirname - 모든 오류가 있다고 가정하고 모든 것을 처리하지 않습니다.) 그리고 ok 버튼을 클릭하면 'dirname' dirname '.내가 간단한 응용 프로그램을 만들고 싶었다

하지만 경로를 전달할 때 './testdir'이라고 말하고 확인을 클릭하면 내 앱이 종료되고 'CREATEDIRECTORY에서 오류가 발생했습니다'라고 표시되며 물론 만들지 않습니다. 무엇이 잘못되었으며이를 해결하는 방법은 무엇입니까?

Windows XP에서 Qt 5.1.1 (MSVC 2010, 32 비트)을 기반으로 Qt Creator 2.8.1 을 사용하고 있습니다.

을 Heres 코드 :

mainwindow.h

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 

namespace Ui { 
class MainWindow; 
} 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

private: 
    Ui::MainWindow *ui; 

public slots: 

    void createdir(); 
}; 

#endif // MAINWINDOW_H 

mainwindow.cpp

#include "mainwindow.h" 
#include "ui_mainwindow.h" 
#include <QDebug> 
#include "Windows.h" 
#include <stdio.h> 
#include <iostream> 

std::string GetLastErrorStdStr() 
{ 
    DWORD error = GetLastError(); 
    if (error) 
    { 
    LPVOID lpMsgBuf; 
    DWORD bufLen = FormatMessage(
     FORMAT_MESSAGE_ALLOCATE_BUFFER | 
     FORMAT_MESSAGE_FROM_SYSTEM | 
     FORMAT_MESSAGE_IGNORE_INSERTS, 
     NULL, 
     error, 
     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
     (LPTSTR) &lpMsgBuf, 
     0, NULL); 
    if (bufLen) 
    { 
     LPCSTR lpMsgStr = (LPCSTR)lpMsgBuf; 
     std::string result(lpMsgStr, lpMsgStr+bufLen); 

     LocalFree(lpMsgBuf); 

     return result; 
    } 
    } 
    return std::string(); 
} 

static const wchar_t *GetWC(const char *c) 
{ 
    const size_t cSize = strlen(c)+1; 
    wchar_t* wc = new wchar_t[cSize]; 
    mbstowcs (wc, c, cSize); 

    return wc; 
} 

LPCWSTR castPath(const char *path) 
{ 
    WCHAR str3[1024]; 
    MultiByteToWideChar(0,0, path, strlen(path), str3, strlen(path)+1); 
    LPCWSTR cstr4 = str3; 
    return cstr4; 
} 

static void makeDir(const char *path) 
{ 
    if(CreateDirectory(castPath(path), NULL) == 0) 
    { 
     printf("ERROR IN CREATEDIRECTORY\n"); 
     std::cout << GetLastErrorStdStr() << "\n"; 
     exit(-1); 
    } 
} 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 

    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(createdir())); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

void MainWindow::createdir() 
{ 
    makeDir(ui->lineEdit->text().toStdString().c_str()); 
} 

MAIN.CPP :

#include "mainwindow.h" 
#include <QApplication> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 

    return a.exec(); 
} 

UI 파일 :

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
<class>MainWindow</class> 
<widget class="QMainWindow" name="MainWindow"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>400</width> 
    <height>300</height> 
    </rect> 
    </property> 
    <property name="windowTitle"> 
    <string>MainWindow</string> 
    </property> 
    <widget class="QWidget" name="centralWidget"> 
    <layout class="QHBoxLayout" name="horizontalLayout"> 
    <item> 
    <widget class="QLineEdit" name="lineEdit"/> 
    </item> 
    <item> 
    <widget class="QPushButton" name="pushButton"> 
     <property name="text"> 
     <string>OK</string> 
     </property> 
    </widget> 
    </item> 
    </layout> 
    </widget> 
    <widget class="QMenuBar" name="menuBar"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>400</width> 
    <height>20</height> 
    </rect> 
    </property> 
    </widget> 
    <widget class="QToolBar" name="mainToolBar"> 
    <attribute name="toolBarArea"> 
    <enum>TopToolBarArea</enum> 
    </attribute> 
    <attribute name="toolBarBreak"> 
    <bool>false</bool> 
    </attribute> 
    </widget> 
    <widget class="QStatusBar" name="statusBar"/> 
</widget> 
<layoutdefault spacing="6" margin="11"/> 
<resources/> 
<connections/> 
</ui> 
+0

''testdir'' 만 경로를 지정하여 디렉토리를 만들면 작동합니까? – vahancho

+0

@vahancho : 아니, 작동하지 않습니다. 방금 새로운 아이디어를 생각해 냈습니다. 문제가 될 수 있다고 생각합니다. VisualStudio에서 일부 응용 프로그램을 빌드 할 때 '유니 코드 문자 세트 사용'에서 ''멀티 바이트 문자 세트 사용 '으로'문자 세트 '를 변경해야 제대로 작동합니다. 여기에 문제가 될 수 있습니까? QtCreator에서 'Character Set'을 어떻게 변경합니까? – yak

+0

'CreateDirectory' 문서를 읽었습니까? 오류 발생시 더 많은 정보를 얻는 방법을 알려줍니다. 그 조언을 따르는 것이 좋습니다. –

답변

3

당신이 어떤 이유는 단순히 QDir::currentPath().mkpath(ui->lineEdit->text())하지? 그 LPCWSTR 외에

이있는 wchar_t* (다른 단순히 문자 *) 그래서 그냥 캐스트

static void makeDir(const wchar_t *path) 
{ 
    if(CreateDirectory((LPCWSTR)path, NULL) == 0) 
    { 
     printf("ERROR IN CREATEDIRECTORY\n"); 
     exit(-1); 
    } 
} 

보다 더 많은 변환을 필요로 해결됩니다

makeDir(ui->lineEdit->text().toStdWString().c_str()); 

으로 호출 것 당신이 넓은 문자 응용 프로그램을 컴파일 한 이후

+0

'경로를 wchar_t'로 변경하는 것 외에 다른 방법이 있습니까? 나는 const char가 될 필요가있다 ... – yak

+1

대신'CreateDirectoryA'를 사용하여'char *'를 취할 수있다 –

+1

@yak 왜 그렇게하고 싶습니까? 더 이상 유니 코드를 지원하지 않으며 Windows는 8 비트 텍스트를 내부적으로 16 비트 UTF-16으로 변환합니다. 국제 지원을 포기할 때 무의미 함. –

1

당신은 CreateDirectoryW을 요구하고있다. 당신은 CreateDirectory 쓰기,하지만 CreateDirectoryW 또는 CreateDirectoryA 하나에 확장 매크로입니다. 당신은 ANSI 텍스트를 인코딩 한 경우

당신은 CreateDirectoryA를 호출 할 수 있습니다. 그러나 국제 텍스트를 제공하지 않는다는 의미이므로 그렇게해서는 안됩니다. QString에 UTF-16으로 인코딩 된 텍스트를 제공하는 것이 쉽습니다. toStdWString을 사용하고 해당 개체에 c_str()으로 전화하십시오. 더 나은 점은 Qt 기능을 사용하고 플랫폼 별 Win32 코드에서 파기를 중지하는 것입니다. 당신은 윈도우 API 함수를 호출하고 실패하면

는 실패를 진단하는 방법을 찾기 위해 문서를 읽어보십시오. 이 경우 GetLastError으로 전화해야합니다. 그래서 그렇게해야합니다.

그러나 배울 수있는 가장 중요한 것은 컴파일러가 타입이 일치하지 않는 사실을 말할 때, 단순히 솔루션 결코 컴파일러 오류를 멀리 캐스팅이다! 오류를 제자리에 남겨두고 관계없이 수행합니다. 컴파일 타임 오류를 런타임 오류로 변환합니다. 전자가 항상 바람직합니다.

+0

감사! 그렇게함으로써 해결 : http://pastie.org/private/2jogzm0wiwc7zlipmdeo2q. 괜찮 았지? – yak

+1

정말 가난합니다. 내부 QString 표현을 ANSII로 변환합니다. 그런 다음 다시 넓은. @ratchet가 제공 한 코드를 사용해야합니다. –

관련 문제