programing

표준 C/C++에서 파일 구분 기호를 가져오는 방법: / 또는 \?

i4 2023. 7. 20. 21:41
반응형

표준 C/C++에서 파일 구분 기호를 가져오는 방법: / 또는 \?

함수를 작성하고 싶습니다.

inline char separator()
{
    /* SOMETHING */
}

표준 C/C++/C++11 ?(시스템에 따라 슬래시 또는 백슬래시를 의미함) 시스템의 파일 구분자를 반환합니다.이것을 달성할 수 있는 방법이 있습니까?

defs를 확인하는 것 말고는 어떻게 해야 할지 잘 모르겠습니다.

inline char separator()
{
#ifdef _WIN32
    return '\\';
#else
    return '/';
#endif
}

또는 (PaperBirdMaster가 제안한 대로)

const char kPathSeparator =
#ifdef _WIN32
                            '\\';
#else
                            '/';
#endif

만약 당신의 컴파일러가 c++17 기능을 제공한다면, 당신은 다음을 사용할 수 있습니다.std::filesystem::path::preferred_separator플랫폼에 따라 선호하는 구분 기호 문자를 생성합니다.으로 "Windows"라는 단어가 됩니다.\반면 리눅스에서는/.

자세한 내용은 이 항목을 참조하십시오.

이 질문은 정말로 훨씬 더 불쾌한 문제를 암시하고 있습니다.

만약 당신이 UNIX와winodws와 사용자는 디렉토리와 파일에만 관심이 있습니다. 그러면 이미 확인한 내용이 대부분 작동하지만, 경로 이름을 구성 요소에 연결하는 보다 일반적인 문제는 훨씬 더 추악한 문제입니다.플랫폼에 따라 경로에는 다음 중 하나 이상이 포함될 수 있습니다.

  • 볼륨 식별자
  • 디렉터리 목록
  • 파일 이름
  • 파일 내의 하위 스트림
  • 버전 번호

이를 위한 서드파티 라이브러리(다양한 CPAN Perl 모듈, Boost 등)가 있고 모든 OS에 이를 위한 시스템 기능이 포함되어 있지만, C++ 표준은 이를 위해 C에 내장된 것이 없으며 2017년에야 Boost 모듈을 통합하여 이 기능을 얻었습니다.

이러한 기능이 처리해야 할 몇 가지 예는 다음과 같습니다.

  • UNIX 및 유닉스 계열 시스템은 "/" 문자로 구분된 문자열 목록을 사용하며, 절대 경로(상대 경로 대)를 나타내는 선행 "/"를 사용합니다.일부 컨텍스트(예: NFS)에는 호스트 이름 접두사(":" 구분 기호)가 있을 수 있습니다.
  • DOS 및 DOS에서 파생된 OS(Windows, OS/2 및 기타)는 "\"를 디렉터리 구분 기호로 사용하지만(API에서도 "/"를 허용함) 경로는 볼륨 정보로 접두사를 붙일 수도 있습니다.드라이브 문자("C:") 또는 UNC 공유 이름("\\MYSERVER\")일 수 있습니다.공유\") 다른 종류의 서버를 나타내는 추가 접두사와 파일 내 기본값이 아닌 스트림을 나타내는 접미사가 있습니다.
  • Mac(클래식 Mac OS, Carbon 및 일부 코코아 API)에서는 ":"를 디렉터리 구분 기호로 사용하며, 첫 번째 용어는 디렉터리 이름이 아니라 볼륨 이름입니다.Mac 파일에는 특수 목적 API를 사용하여 동일한 이름을 통해 액세스되는 하위 스트림("포크")이 포함될 수도 있습니다.이는 클래식 Mac 소프트웨어에서 광범위하게 사용되는 리소스 포크에 특히 중요합니다.
  • Mac OS X는 UNIX API를 사용할 때 일반적으로 UNIX와 유사한 시스템이 수행하는 작업을 수행하지만 파일 이름에 "." 뒤에 포크 이름을 붙여 명명된 하위 스트림("포크")을 나타낼 수도 있습니다.
  • 코코아의 최신 버전(Mac OS X, iOS 등)은 이 문제의 복잡성이 계속 증가하고 있기 때문에 URL 기반 API를 사용하여 파일을 표시할 것을 권장합니다.클라우드 기반 문서 및 기타 복잡한 네트워크 파일 시스템을 생각해 보십시오.
  • VMS는 상당히 복잡합니다(https://web.archive.org/web/20160324205714/http ://www.djesys.com/vms/freevms/mentor/vms_path.html), ). 그러나 볼륨, 디렉토리 경로, 파일 및 파일 경로를 나타내는 구성 요소가 있습니다.

다른 것들도 많이 있습니다.

C++17 파일 시스템 라이브러리가 이러한 모든 가능성을 다루지 않는다는 것에 주목할 필요가 있습니다.std::filesystem::path선택적 루트 이름(볼륨 식별자), 절대 경로를 식별하는 선택적 루트 디렉터리 및 디렉터리 구분 기호로 구분된 일련의 파일 이름으로 구성됩니다.여기에는 UNIX 플랫폼에서 유효할 가능성이 있는 모든 것과 다른 플랫폼의 대부분의 사용 사례가 포함되지만 포괄적이지는 않습니다.예를 들어, 서브스트림은 지원되지 않습니다(Mac OS X에서 수행되지만 클래식 MacOS가 아닌 파일 이름에 어떻게든 매핑하기 위해 OS에 의존합니다).또한 파일 버전 번호에 대한 지원도 포함되어 있지 않습니다.

경로 및 C++17 표준:: 파일 시스템:: 경로 클래스에 대한 위키백과의 항목도 참조하십시오.

http://en.cppreference.com/w/cpp/filesystem

디렉터리 구분자로 수행할 작업(기본 이름 추출, 디렉터리 목록으로 경로 나누기 등)을 살펴보고 이를 위한 함수를 작성하는 것이 좋습니다.만약 당신이 C++17을 사용하고 있다면 (그리고 당신의 코드가 17 이전의 C++ 컴파일러에 의해 컴파일되지 않을 것이 확실하다면) 표준 C++ 라이브러리 코드를 사용하여 이 함수의 휴대용 구현체를 작성할 수 있습니다. 그렇않경해기당플능합사니다로용야해별랫을 사용해야 합니다.#ifdef각 는 지할각에대한사용을 합니다.#error조건이 하나도 충족되지 않는 경우 예기치 않은 플랫폼에 대한 조건을 추가하도록 강제합니다.

또는 이 모든 기능이 포함된 타사 라이브러리(예: Boost)를 사용하십시오.

그것은 이런 것일 수 있습니다.

#if defined(WIN32) || defined(_WIN32) 
#define PATH_SEPARATOR "\\" 
#else 
#define PATH_SEPARATOR "/" 
#endif 

승인된 답변은 Cygwin에서 작동하지 않습니다.Windows에서 실행되는 Cygwin 컴파일 프로그램은 Windows 스타일 '\' 구분자를 사용할 수 있지만 _WIN32 등을 정의하지 않습니다.Cygwin에서 작동하는 수정된 솔루션:

inline char separator()
{
#if defined _WIN32 || defined __CYGWIN__
    return '\\';
#else
    return '/';
#endif
}

또는

const char kPathSeparator =
#if defined _WIN32 || defined __CYGWIN__
    '\\';
#else
    '/';
#endif

std::filesystem::path::preferred_separator 이제 클린으로 사용해야 합니다.C++17보이는 대로 라이브러리 기능.

아무도 다음과 같은 제안을 하지 않은 것이 놀랍습니다.이것은 다른 사람들이 여기서 제공하는 것을 기반으로 합니다.

이 예에서는 사용하기 위해 실행 중인 실행 파일의 이름을 동적으로 가져오려고 하지만 필요에 따라 점프를 수행하고 다시 적용하는 것은 그리 어렵지 않습니다.

Windows에서는 슬래시를 사용하여 인수를 나타냅니다.그래서 당신은 첫 번째 논쟁에서 그것을 먼저 확인할 수 있습니다.argv[0]실행 중인 프로그램의 이름을 포함합니다.

다음 결과는 마지막 슬래시 이전의 경로 이름을 제거한 후에 종료됩니다.sepd프로그램의 파일 이름으로 사용합니다.

#include <string.h>
#include <stdio.h>

int main(int argc, char *argv[]){
//int a = 1
//int this = (a == 1) ? 20 : 30;  //ternary operator
//is a==1 ? If yes then 'this' = 20, or else 'this' = 30
    char *sepd = (strrchr(argv[0], '\/') != NULL) ? 
        strrchr(argv[0], '\/') : 
        strrchr(argv[0], '\\');
    printf("%s\n\n", sepd);
    printf("usage: .%s <host> \n\n", sepd);
    while (getchar() != '\n');
}

그러나 모든 현실에서 이것은 상당히 더러운 일이며, Bash(현재는 아직 구현되지 않음)를 포함하려는 Windows의 가장 최근 움직임으로 인해 예상치 못했거나 예상치 못한 결과를 초래할 수 있습니다.

또한 다른 사람들이 제공한 것처럼 제정신이 아니며 오류에 영향을 받지 않습니다. 특히.#ifdef _WIN32.

언급URL : https://stackoverflow.com/questions/12971499/how-to-get-the-file-separator-symbol-in-standard-c-c-or

반응형