Получить расширение файла c
Дана строка "filename.conf" , Как проверить Часть расширения?
Мне нужно кросс-платформенное решение.
вы должны убедиться, что вы заботитесь о имена файлов с более чем одной точкой. пример: c:\.directoryname\file.name.with.too.many.dots.ext не будет правильно обрабатываться strchr или find.
моим любимым будет повысить библиотеку файловой системы которые имеют функцию расширения (пути)
это слишком простое решение?
лучший способ-не писать код, который это делает, а вызывать существующие методы. В windows,PathFindExtension метод, вероятно, самый простой.
Так почему бы вам не написать свой собственный?
ну, возьмем пример strrchr, что происходит, когда вы используете этот метод в следующей строке "c:\program файлы\AppleGate.Net\readme"? Является ли расширение" .Net\readme"? Легко написать что-то, что работает для нескольких примеров, но может быть много труднее написать что-то, что работает для всех случаев.
предполагая, что у вас есть доступ к STL:
Edit: это кросс-платформенное решение, так как вы не упомянули платформу. Если вы находитесь конкретно в Windows, вы захотите использовать определенные функции Windows, упомянутые другими в потоке.
кто-то еще упомянул boost, но я просто хотел добавить фактический код для этого:
на самом деле STL может сделать это без особого кода, я советую вам узнать немного о STL, потому что он позволяет вам делать некоторые причудливые вещи, в любом случае это то, что я использую.
это решение всегда будет возвращать расширения даже на строки вроде "этого.а.б.С. д.е.С. МР3", если он не может найти расширение, он вернется "".
на самом деле, самый простой способ-это
одно нужно помнить: если '.' не существует в filename, ext будет NULL .
Я сам наткнулся на этот вопрос сегодня, хотя у меня уже был рабочий код, я понял, что в некоторых случаях он не будет работать.
хотя некоторые люди уже предложили использовать некоторые внешние библиотеки, я предпочитаю писать свой собственный код для целей обучения.
некоторые ответы включали метод, который я использовал в первую очередь (поиск последнего "."), но я вспомнил, что в linux скрытые файлы / папки начинаются с ".". Поэтому, если файл file скрыт и имеет нет расширения, все имя файла будет принято за расширение. Чтобы избежать этого, я написал этот кусок кода:
Я не тестировал это полностью, но я думаю, что это должно работать.
Я думаю, что это только Windows (Platform SDK)?
использование std:: string find / rfind решает эту проблему, но если вы много работаете с путями, то вы должны посмотреть на boost::filesystem::path, так как это сделает ваш код намного чище, чем возиться с необработанными строковыми индексами/итераторами.
Я предлагаю boost, поскольку это высококачественная, хорошо протестированная (с открытым исходным кодом и коммерчески) бесплатная и полностью портативная библиотека.
для строк типа массива char вы можете использовать следующее:
может обрабатывать пути к файлам в дополнение к именам файлов. Работает с C и C++. И кросс-платформенный.
вы можете использовать приведенный выше код в приложении на C++, как показано ниже:
последний пункт в некоторых случаях папка a присваивается имени файла в качестве аргумента и включает точку в имени папки функция будет возвращать точку папки, так что лучше сначала пользователю проверить, что данное имя является именем файла, а не именем папки.
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Примеры
В следующем примере показаны некоторые основные члены FileInfo класса.
При первом получении FileInfo свойств вызывает Refresh метод и кэширует сведения о файле. При последующих вызовах необходимо позвонить Refresh , чтобы получить последнюю копию информации.
В этом примере создаются выходные данные, аналогичные приведенному ниже.
Перегрузки
Возвращает расширение из пути к файлу, представленного диапазоном символов только для чтения.
Возвращает расширение указанной строки пути (включая точку ".").
GetExtension(String)
Возвращает расширение указанной строки пути (включая точку ".").
Параметры
Строка пути, из которой нужно получить расширение.
Возвращаемое значение
Расширение указанного пути (включая точку ".") или значение null или Empty. Если параметр path имеет значение null , GetExtension(String) возвращает null . Если параметр path не содержит сведений о расширении, GetExtension(String) возвращает Empty.
Исключения
Примеры
В следующем примере показано использование GetExtension метода на классической платформе на основе Windows.
Применяется к
Комментарии
FileInfo Используйте класс для типичных операций, таких как копирование, перемещение, переименование, создание, открытие, удаление и добавление к файлам.
При выполнении нескольких операций в одном файле можно более эффективно использовать FileInfo методы экземпляра вместо соответствующих статических методов File класса, так как проверка безопасности не всегда требуется.
FileInfo Многие методы возвращают другие типы ввода-вывода при создании или открытии файлов. Эти другие типы можно использовать для дальнейшего управления файлом. Дополнительные сведения см. в конкретных FileInfo элементах, таких как Open, , OpenRead, OpenTextCreateTextили Create.
По умолчанию всем пользователям предоставляется полный доступ на чтение и запись к новым файлам.
В следующей таблице описаны перечисления, используемые для настройки поведения различных FileInfo методов.
Перечисление | Описание |
---|---|
FileAccess | Указывает доступ на чтение и запись к файлу. |
FileShare | Указывает уровень доступа, разрешенный для файла, который уже используется. |
FileMode | Указывает, сохраняется ли содержимое существующего файла или перезаписывается, а также указывает, вызывают ли запросы на создание существующего файла исключение. |
В членах, которые принимают путь в качестве входной строки, этот путь должен быть правильно сформирован или возникает исключение. Например, если путь является полным, но начинается с пробела, путь не обрезается в методах класса. Таким образом, путь имеет неправильный формат и возникает исключение. Аналогичным образом путь или сочетание путей не могут быть полностью квалифицированы дважды. Например, "c:\temp c:\windows" также вызывает исключение в большинстве случаев. Убедитесь, что пути правильно сформированы при использовании методов, которые принимают строку пути.
В членах, которые принимают путь, путь может ссылаться на файл или только каталог. Указанный путь также может ссылаться на относительный путь или UNC-путь для сервера и имени общего ресурса. Например, все следующие допустимые пути:
Класс FileInfo предоставляет следующие свойства, позволяющие получать сведения о файле. Пример использования каждого свойства см. на страницах свойств.
Свойство Directory извлекает объект, представляющий родительский каталог файла.
Свойство DirectoryName получает полный путь к родительскому каталогу файла.
Свойство Exists проверяет наличие файла перед его выполнением.
Свойство IsReadOnly извлекает или задает значение, указывающее, можно ли изменить файл.
Извлекает Length размер файла.
Извлекает Name имя файла.
См. также раздел
Методы расширения
Создает файловый поток с указанными свойствами и параметрами безопасности.
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Выполняет операции для экземпляров класса String, содержащих сведения о пути к файлу или каталогу. Эти операции выполняются межплатформенным способом.
Комментарии
Путь — это строка, предоставляющая расположение файла или каталога. Путь не обязательно указывает на расположение на диске; Например, путь может сопоставляться с расположением в памяти или на устройстве. Точный формат пути определяется текущей платформой. Например, в некоторых системах путь может начинаться с буквы диска или тома, а этот элемент отсутствует в других системах. В некоторых системах пути к файлам могут содержать расширения, которые указывают тип информации, хранящейся в файле. Формат расширения имени файла зависит от платформы; Например, некоторые системы ограничивают расширения до трех символов (например, FAT16, которые обычно используются в меньшем хранилище флэш-памяти и более старых версиях ISO 9660, используемых на оптических носителях), а другие — нет. Текущая платформа также определяет набор символов, используемых для разделения элементов пути, и набор символов, которые нельзя использовать при указании путей. Из-за этих различий поля Path класса, а также точное поведение некоторых членов Path класса зависят от платформы.
Путь может содержать абсолютные или относительные сведения о расположении. Абсолютные пути полностью указывают расположение: файл или каталог можно однозначно определить независимо от текущего расположения. Относительные пути указывают частичное расположение: текущее расположение используется в качестве отправной точки при поиске файла, указанного с относительным путем. Чтобы определить текущий каталог, вызовите Directory.GetCurrentDirectory.
.NET Core 1.1 и более поздних версий и платформа .NET Framework 4.6.2 и более поздних версий также поддерживают доступ к объектам файловой системы, которые являются именами устройств, например "\\?\ C:\".
Дополнительные сведения о форматах пути к файлам в Windows см. в форматах пути к файлам в системах Windows.
Большинство членов Path класса не взаимодействуют с файловой системой и не проверяют наличие файла, указанного строкой пути. Path Члены класса, изменяющие строку пути, например ChangeExtension, не влияют на имена файлов в файловой системе.
Члены Path класса позволяют быстро и легко выполнять общие операции, такие как определение того, является ли расширение имени файла частью пути, и объединять две строки в одно имя пути.
Все члены Path класса являются статическими и поэтому могут вызываться без экземпляра пути.
В членах, которые принимают путь в качестве входной строки, этот путь должен быть правильно сформирован или возникает исключение. Например, если путь является полным, но начинается с пробела, путь не обрезается в методах класса. Таким образом, путь имеет неправильный формат и возникает исключение. Аналогичным образом путь или сочетание путей не могут быть полностью квалифицированы дважды. Например, "c:temp c:\\windows" также вызывает исключение в большинстве случаев. Убедитесь, что пути правильно сформированы при использовании методов, которые принимают строку пути.
В членах, которые принимают путь, путь может ссылаться на файл или только каталог. Указанный путь также может ссылаться на относительный путь или UNC-путь для сервера и имени общего ресурса. Например, все следующие допустимые пути:
Так как все эти операции выполняются в строках, невозможно проверить, являются ли результаты допустимыми во всех сценариях. Например, метод анализирует строку, GetExtension передаваемую в нее, и возвращает расширение из этой строки. Однако это не означает, что на диске существует файл с этим расширением.
Список распространенных задач ввода-вывода см. в разделе "Общие задачи ввода-вывода".
Предоставляет дополнительный символ, задаваемый платформой, для разделения уровней каталогов в строке пути, в которой отражена иерархическая организация файловой системы.
Предоставляет символ, задаваемый платформой, для разделения уровней папок в строке пути, в которой отражена иерархическая организация файловой системы.
Предоставляет массив символов, задаваемых платформой, которые не могут быть указаны в аргументах строки пути, передаваемых в элементы класса Path.
Разделитель, задаваемый платформой, который используется в переменных среды для разделения строк пути.
Предоставляет разделитель томов, задаваемый платформой.
Методы
Изменяет расширение строки пути.
Объединяет две строки в путь.
Объединяет три строки в путь.
Объединяет четыре строки в путь.
Объединяет массив строк в путь.
Возвращает значение, указывающее, заканчивается ли путь, заданный в качестве диапазона, доступного только для чтения, в разделителе каталогов.
Возвращает значение, указывающее, заканчивается ли заданный путь в разделителе каталогов.
Определяет, существует ли указанный файл или каталог.
Возвращает сведения о каталоге для указанного пути, представленного диапазоном символов.
Возвращает сведения о каталоге для указанного пути.
Возвращает расширение из пути к файлу, представленного диапазоном символов только для чтения.
Возвращает расширение указанной строки пути (включая точку ".").
Возвращает имя и расширение файла из пути к файлу, представленного диапазоном символов только для чтения.
Возвращает имя файла и расширение указанной строки пути.
Возвращает имя файла без расширения из пути к файлу, представленного диапазоном символов только для чтения.
Возвращает имя файла указанной строки пути без расширения.
Возвращает для указанной строки пути абсолютный путь.
Возвращает абсолютный путь из относительного пути и полного базового пути.
Возвращает массив, содержащий символы, которые не разрешены в именах файлов.
Возвращает массив, содержащий символы, которые не разрешены в именах путей.
Получает сведения о корневом каталоге из пути, содержащегося в указанном диапазоне символов.
Получает сведения о корневом каталоге из пути, содержащегося в указанной строке.
Возвращает произвольное имя каталога или файла.
Возвращает относительный путь от одного пути к другому.
Создает на диске временный пустой файл с уникальным именем и возвращает полный путь этого файла.
Возвращает путь к временной папке текущего пользователя.
Определяет, включает ли путь, представленный указанным диапазоном символов, расширение имени файла.
Определяет, включает ли путь расширение имени файла.
Возвращает значение, которое показывает, является ли путь к файлу, представленный указанным диапазоном символов, фиксированным для определенного диска или UNC-пути.
Возвращает значение, которое показывает, является ли указанный путь к файлу фиксированным для определенного диска или UNC-пути.
Возвращает значение, которое показывает, содержит ли указанный диапазон символов, являющийся путем к файлу, корневую папку.
Возвращает значение, показывающее, содержит ли указанная строка пути корневую папку.
Сцепляет два компонента пути в один путь.
Сцепляет три компонента пути в один путь.
Сцепляет четыре компонента пути в один путь.
Сцепляет два пути в один путь.
Сцепляет три пути в один путь.
Сцепляет четыре пути в один путь.
Сцепляет массив путей в один путь.
Обрезает один конечный разделитель каталогов за пределами корня указанного пути.
Обрезает один конечный разделитель каталогов за пределами корня указанного пути.
Пытается объединить три компонента пути к одному предварительно размещенному диапазону символов и возвращает значение, указывающее, выполнена ли операция успешно.
Пытается сцепить два компонента пути в один предварительно выделенный диапазон символов и возвращает значение, показывающее, успешно ли выполнена эта операция.
Given a string "filename.conf" , how to I verify the extension part?
I need a cross platform solution.
This question was from 2008, but if you came here today, see std::filesystem::path which is standard (since c++17) and cross-platform. As mentioned below by Roi Danton and yves.
Свойства
Получает или задает атрибуты для текущего файла или каталога.
Получает или задает время создания текущего файла или каталога.
Получает или задает время создания текущего файла или каталога в формате UTC.
Получает экземпляр родительского каталога.
Получает строку, представляющую полный путь к каталогу.
Получает значение, показывающее, существует ли файл.
Возвращает часть расширения имени файла, включая начальную точку . даже если это имя файла целиком или пустая строка, если расширение отсутствует.
Получает полный путь к каталогу или файлу.
Возвращает или задает значение, позволяющее определить, является ли текущий файл доступным только для чтения.
Получает или задает время последнего доступа к текущему файлу или каталогу.
Получает или задает дату и время последнего доступа к заданному файлу или каталогу в формате всеобщего скоординированного времени (UTC).
Получает или задает время последней операции записи в текущий файл или каталог.
Получает или задает время последней операции записи в текущий файл или каталог в формате всеобщего скоординированного времени (UTC).
Получает размер текущего файла в байтах.
Получает целевой путь ссылки, расположенной в FullName, или null если этот FileSystemInfo экземпляр не представляет ссылку.
Получает имя файла.
Примеры
В следующем примере показаны некоторые основные члены Path класса.
Методы
Создает StreamWriter, который добавляет текст в файл, представленный этим экземпляром FileInfo.
Копирует существующий файл в новый файл и запрещает перезапись существующего файла.
Копирует существующий файл в новый файл и разрешает перезапись существующего файла.
Создает символьную ссылку, расположенную в FullName этой точке на указанный pathToTarget .
Создает объект, который содержит всю необходимую информацию для создания прокси-сервера, используемого для взаимодействия с удаленным объектом.
Создает StreamWriter, который записывает новый текстовый файл.
Расшифровывает файл, зашифрованный текущей учетной записью с помощью метода Encrypt().
Удаляет файл без возможности восстановления.
Шифрует файл таким образом, чтобы его можно было расшифровать только с помощью учетной записи, которая использовалась для шифрования.
Определяет, равен ли указанный объект текущему объекту.
Возвращает объект FileSecurity, который инкапсулирует записи списка управления доступом (ACL) для файла, описываемого текущим объектом FileInfo.
Получает объект FileSecurity, который инкапсулирует заданный тип записей списка управления доступом для файла, описываемого текущим объектом FileInfo.
Служит хэш-функцией по умолчанию.
Извлекает объект обслуживания во время существования, который управляет политикой времени существования данного экземпляра.
Устанавливает объект SerializationInfo с именем файла и дополнительными сведениями об исключении.
Возвращает объект Type для текущего экземпляра.
Получает объект службы времени существования для управления политикой времени существования для этого экземпляра.
Создает неполную копию текущего объекта Object.
Создает неполную копию текущего объекта MarshalByRefObject.
Перемещает заданный файл в новое местоположение и разрешает переименование файла.
Перемещает указанный файл в новое расположение, предоставляя параметры для указания нового имени файла и перезаписи конечного файла, если он уже существует.
Открывает файл в заданном режиме.
Открывает файл в заданном режиме с доступом для чтения или записи, или и для чтения, и для записи.
Открывает файл в заданном режиме с доступом для чтения, записи или и для чтения, и для записи и с заданным параметром совместного доступа.
Инициализирует новый экземпляр FileStream класса с указанным режимом создания, разрешением на чтение и запись и общий доступ, доступ к другим fileStreams может иметь тот же файл, размер буфера, дополнительные параметры файла и размер выделения.
Создает доступный только для чтения поток FileStream.
Создает поток StreamReader с кодировкой UTF-8, который считывает данные из существующего текстового файла.
Создает доступный только для чтения поток FileStream.
Обновляет состояние объекта.
Заменяет содержимое заданного файла на содержимое файла, которое описано в текущем объекте FileInfo, удаляет исходный файл и создает резервную копию замененного файла.
Заменяет содержимое заданного файла на содержимое файла, которое описано в текущем объекте FileInfo, удаляет исходный файл и создает резервную копию замененного файла. Также позволяет определить, нужно ли игнорировать ошибки слияния.
Возвращает целевой объект указанной ссылки.
Применяет записи списка управления доступом (ACL), описанные объектом FileSecurity, к файлу, который описывается текущим объектом FileInfo.
Возвращает путь в виде строки. Используйте свойство Name для полного пути.
Возвращает исходный путь. Используйте свойства FullName или Name для полного пути или имени файла или каталога.
Комментарии
Этот метод получает расширение path путем поиска path точки (.), начиная с последнего символа path и продолжая к первому символу. Если точка найдена до или DirectorySeparatorChar AltDirectorySeparatorChar символа, возвращаемая строка содержит точку и символы после нее; в противном случае String.Empty возвращается.
Список распространенных задач ввода-вывода см. в разделе "Общие задачи ввода-вывода".
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Предоставляет свойства и методы экземпляра для создания, копирования, удаления, перемещения и открытия файлов, а также позволяет создавать объекты FileStream. Этот класс не наследуется.
26 Answers 26
Is this too simple of a solution?
By that logic, you could just say return "Yes. "; with no check at all - it's implied that the solution should work for other inputs. As another counter example, a file named simply "conf" with no extension would also return "Yes. " given the above.
The best way is to not write any code that does it but call existing methods. In windows, the PathFindExtension method is probably the simplest.
So why would you not write your own?
Well, take the strrchr example, what happens when you use that method on the following string "c:\program files\AppleGate.Net\readme"? Is ".Net\readme" the extension? It is easy to write something that works for a few example cases, but can be much harder to write something that works for all cases.
This function (under Windows 7) will not properly handle "file.i i". Yes, this is valid, notice the space.
He has asked about retrieving the extension from a file, not a full path. In addition, a Windows API function would not be a good answer. This is absolutely not an answer, but a comment.
+1 From me. This question is the first one that comes up when you google 'mfc get file extension', and yours is the simplest answer that works.
You have to make sure you take care of file names with more then one dot. example: c:\.directoryname\file.name.with.too.many.dots.ext would not be handled correctly by strchr or find.
My favorite would be the boost filesystem library that have an extension(path) function
In my personal opinion boost solutions should not be listed as answers to c++ problems. Requiring a external library for something so simple seems a bit silly.
@marsh: yet, the so simple problem has its special cases, especially when dealing with file systems - a concept which almost every major (and not so major) operating system has its own interpretation for. Consider, e.g., linux hidden files (`/home/oren/.conf'), or the case mentioned by @Torlack. @17 of 26, trying to mention your username alone should highlight the problems which may arise from over-simplifying how people use free-form naming ;)
@OrenS Nonetheless, boost solution should not be ever accepted as the answer to a question that doesn't ask how to do it with boost. It's misleading.
@MuhamedCicak . well, portable solution for othervise involves some long piece of code which takes in account encoding of file names or/and use other libraries (i suspect boost doesn't implement it from scratch, instead uses other packages or API where possible). Note, that even getting canonical path from partial one as a task is a huge problem with half-dozen of edge cases.
Assuming you have access to STL:
Edit: This is a cross platform solution since you didn't mention the platform. If you're specifically on Windows, you'll want to leverage the Windows specific functions mentioned by others in the thread.
With C++17 and its std::filesystem::path::extension (the library is the successor to boost::filesystem) you would make your statement more expressive than using e.g. std::string .
Someone else mentioned boost but I just wanted to add the actual code to do this:
+1, thanks for posting an actual code snippet using boost. Don't forget to link with -lboost_filesystem and you get a working solution.
actually the STL can do this without much code, I advise you learn a bit about the STL because it lets you do some fancy things, anyways this is what I use.
this solution will always return the extension even on strings like "this.a.b.c.d.e.s.mp3" if it cannot find the extension it will return "".
Actually, the easiest way is
One thing to remember: if '.' doesn't exist in filename, ext will be NULL .
I've stumbled onto this question today myself, even though I already had a working code I figured out that it wouldn't work in some cases.
While some people already suggested using some external libraries, I prefer to write my own code for learning purposes.
Some answers included the method I was using in the first place (looking for the last "."), but I remembered that on linux hidden files/folders start with ".". So if file file is hidden and has no extension, the whole file name would be taken for extension. To avoid that I wrote this piece of code:
I haven't tested this fully, but I think that it should work.
I'd go with boost::filesystem::extension ( std::filesystem::path::extension with C++17) but if you cannot use Boost and you just have to verify the extension, a simple solution is:
Using std::string's find/rfind solves THIS problem, but if you work a lot with paths then you should look at boost::filesystem::path since it will make your code much cleaner than fiddling with raw string indexes/iterators.
I suggest boost since it's a high quality, well tested, (open source and commercially) free and fully portable library.
For char array-type strings you can use this:
Can handle file paths in addition to filenames. Works with both C and C++. And cross-platform.
You could decrease number of conditions. Use strlen(extension) in for condition. Then if chars does not match return false. Outside for loop return true.
If you use Qt library, you can give a try to QFileInfo's suffix()
What does Qt have to do with this question? Why introduce a large third-party dependency for a simple string manipulation? If going that route, why not just use boost?
@derpface It's if you use it. Since it's common, if you're using it, suffix() is in there and works fine. If you aren't using it, it'd obviously be silly to move your entire project over to Qt just for getting file extensions.
Good answers but I see most of them has some problems: First of all I think a good answer should work for complete file names which have their path headings, also it should work for linux or windows or as mentioned it should be cross platform. For most of answers; file names with no extension but a path with a folder name including dot, the function will fail to return the correct extension: examples of some test cases could be as follow:
"brian newman" suggestion will fail for filename1 and filename4. and most of other answers which are based on reverse find will fail for filename1. I suggest including the following method in your source: which is function returning index of first character of extension or the length of given string if not found.
you could use the above code in your c++ application like below:
The last point in some cases the a folder is given to file name as argument and includes a dot in the folder name the function will return folder's dot trailing so better first to user check that the given name is a filename and not folder name.
Конструкторы
Выполняет инициализацию нового экземпляра класса FileInfo, который служит оболочкой для пути файла.
Представляет полный путь к каталогу или файлу.
Первоначально заданный пользователем относительный или абсолютный путь.
Комментарии
Этот метод получает расширение path путем поиска path точки ("."), начиная с последнего символа в диапазоне только для чтения и продолжая к первому символу. Если точка найдена до или DirectorySeparatorChar AltDirectorySeparatorChar символа, возвращаемый диапазон только для чтения содержит точку и символы после нее; в противном случае ReadOnlySpan.Empty возвращается.
GetExtension(ReadOnlySpan)
Возвращает расширение из пути к файлу, представленного диапазоном символов только для чтения.
Параметры
Путь к файлу, из которого необходимо получить расширение.
Возвращаемое значение
Расширение указанного пути (включая точку — ".") или Empty, если в path отсутствуют сведения о расширении.
Читайте также: