2017-01-02 2 views
-1

Я не знаю, что здесь произошло. Вот пример кода:Что-то плохое в понимании в «SetCurrentDirectory» («windows.h») в CPP

#include<stdio.h> 
#include<iostream> 
#include<string> 
#include <Windows.h> 
using namespace std; 
int main() 
{ 
    char my_current_path[1024]; 
    string current_path(R"(C:)"); 
    if (!SetCurrentDirectory(current_path.c_str())) 
     cout << "cant change to that directory."; 
    GetCurrentDirectory(1024, my_current_path); 
    std::cout << my_current_path << endl; 
    system("pause"); 
    return 1; 
} 

Что я здесь делаю, это попытка сменить каталог на некоторые каталоги.

С моим кодом есть две странные вещи.

(1 Странная вещь)

Когда я пытаюсь изменить на «C:» так:

#include<stdio.h> 
#include<iostream> 
#include<string> 
#include <Windows.h> 
using namespace std; 
int main() 
{ 
    char my_current_path[1024]; 
    string current_path(R"(C:)"); 
    if (!SetCurrentDirectory(current_path.c_str())) 
     cout << "cant change to that directory."; 
    GetCurrentDirectory(1024, my_current_path); 
    std::cout << my_current_path << endl; 
    system("pause"); 
    return 1; 
} 

Это не работает и не меняя пути (и его хорошую вещь.), но не покажет мне сообщение, которое отображается, когда каталог не изменен:

cout << "cant change to that directory."; 

Почему это? (Когда я пытаюсь изменить что-то вроде «efef:» или «exist?», Это показывает мне, что это messege. Но почему здесь это не показывает меня, а также может изменить текущий рабочий каталог?

(Second Странная вещь)

Когда я изменить каталог на «G:» ИТС по некоторым причинам рабочий ..

#include<stdio.h> 
#include<iostream> 
#include<string> 
#include <Windows.h> 
using namespace std; 
int main() 
{ 
    char my_current_path[1024]; 
    string current_path(R"(G:)"); 
    if (!SetCurrentDirectory(current_path.c_str())) 
     cout << "cant change to that directory."; 
    GetCurrentDirectory(1024, my_current_path); 
    std::cout << my_current_path << endl; 
    system("pause"); 
    return 1; 
} 

Этот код компилируется, показывая, что я успешно изменил каталог на «G:». После перехода на этот путь я пытаюсь перейти на «C:» (что раньше, ничего не делал), и теперь это работа! но странным образом, его не движется к «C: \» Но:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE 

И это странно, что до его не работала, а теперь, когда я нахожусь в «G:» путь и пытается перейти «c:» снова, затем его движение к пути, которого я даже не хотел!

+1

'Если функция не работает, возвращаемое значение равно нулю. Чтобы получить расширенную информацию об ошибке, вызовите GetLastError.' Итак, добавьте некоторую проверку ошибок, чтобы вы знали, почему она терпит неудачу. –

+1

why '" (C :) "' вы можете только '" C: \\ "' – Raindrop7

+0

@RetiredNinja Не удалось изменить каталог, но не попал в if (есть if, если для случая он возвращает ноль –

ответ

4

Если вы хотите, чтобы указать корневой каталог на диске, вы должен включать обратную косую черту, т.е. C:\.

Синтаксис, который вы используете, C:, имеет другое значение. Командная оболочка разделяет понятия текущего диска и текущего каталога на каждом диске, так что вы можете быстро переключаться между дисками, не переписывая полный путь каждый раз. Эта функция была введена (давным-давно) по причинам обратной совместимости (см. Ниже), но на самом деле очень полезна; опытные пользователи иногда сопоставляют несколько букв диска с одним и тем же диском или сетевым ресурсом, чтобы использовать эту функциональность.

Хотя только командная оболочка отслеживает текущий каталог для каждого диска, API Win32 знает, как их искать, и делает это всякий раз, когда вы указываете диск, но нет пути. В качестве особого случая, если указанный диск является текущим диском, он расширяется до фактического текущего каталога, а не из сохраненного текущего каталога.

Итак, в вашем примере неполный путь C: расширен до текущего каталога для привода C; поскольку ваш текущий каталог уже находится на диске C, SetCurrentDirectory(R"(C:)") не является оператором. Если вы хотите изменить корневой каталог, вместо этого вы должны использовать SetCurrentDirectory(R"(C:\)").

В вашем тестировании не было сохраненного текущего каталога для диска G:, и он не был текущим диском, поэтому эффект заключался в том, чтобы установить текущий каталог на G:\, то есть вы получили поведение, которое вы ожидали, но не для Причина, по которой вы ожидали. Если вы запустили программу из командной оболочки, и текущий каталог был сохранен для диска G, вы бы туда попали.

То же самое относится к открывающим файлам; C:file.txt откроет file.txt из текущего каталога для привода C, тогда как C:\file.txt откроет file.txt из корневого каталога.

См. Сообщение в блоге Raymond Chen, Why does each drive have its own current directory? для обсуждения истории этой функции.

0

вы можете использовать два API-интерфейсы для извлечения и установки текущего каталога: GetCurrentDirectory() и SetCurrentDirectory() только обеспечивают правильный путь для последнего:

#include <iostream> 
#include <windows.h> 
using namespace std; 


int main() 
{ 
    char czCurDir[MAX_PATH] = ""; 
    char czNewDir[MAX_PATH] = ""; 

    // retrieve the current directory 
    GetCurrentDirectory(MAX_PATH, czCurDir); 
    cout << "Current directory: " << czCurDir << endl;// C:\Users\Raindrop7\Desktop\New folder 

    // set the value for the new directory NB: C:\\ not C:\ because the first backslah is an escape character 
    strcpy(czNewDir, "C:\\"); 

    // set the current directory to "C:\" 
    SetCurrentDirectory(czNewDir); 

    // retrieve the current directory 
    GetCurrentDirectory(MAX_PATH, czCurDir); 

    cout << "current directory: " << czCurDir << endl;// C:\ 


    return 0; 
}