Как изменить расширение имени файла, хранящееся в строке в C++?

хорошо, вот сделка, я беру введение в класс C++ в моем университете и у меня возникли проблемы с выяснением, как изменить расширение файла. Во-первых, то, что мы должны сделать, это прочитать в a .тхт файл и посчитать слова, предложения, гласных и т. д. Ну, я получил это, но следующий шаг-это то, что меня беспокоит. Затем мы должны создать новый файл, используя то же имя файла, что и входной файл, но с расширением .вместо кода .txt (в этом новом файле мы должны затем кодировать строку добавление случайных чисел в код ASCII каждого символа, если вам интересно). Будучи новичком в программировании, я не совсем уверен, как это сделать. Я использую следующий фрагмент кода, чтобы сначала получить входной файл:

cout << "Enter filename: ";
cin >> filename;
infile.open(filename.c_str());

Я предполагаю создать новый файл, который я собираюсь использовать что-то вроде:

outfile.open("test.code");

но я не буду знать, что такое имя файла, пока пользователь не введет его, поэтому я не могу сказать "тест.формат txt." Поэтому, если кто-нибудь знает, как изменить это расширение, когда я создайте новый файл, я был бы очень признателен!

13 ответов


Существует несколько подходов к этому.

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

infile.open(filename + ".txt");

тогда вы просто позвоните

outfile.open(filename + ".code");

следующим подходом было бы взять все имя файла, включая расширение, и просто добавить .код к нему, чтобы у вас был тест.формат txt.код.

это немного неоднозначно, если это приемлемо или нет.

наконец, вы можете использовать std::string методы find и replace получить имя файла без расширения, и использовать это.


конечно, если бы это была не домашняя работа, а реальный проект, вы, вероятно, сделали бы себе-а также другим людям, читающим ваш код-услугу, используя импульс.Файловая система ' s replace_extension() вместо прокатки свой собственный. Там просто нет функциональности, которая достаточно проста, чтобы вы не могли придумать ошибку, по крайней мере, в каком-то угловом случае.


Я иногда задаю себе этот вопрос и оказываюсь на этой странице, поэтому для дальнейшего использования вот однострочный синтаксис:

string newfilename=filename.substr(0,filename.find_last_of('.'))+".code";

не отдавать его, так как обучение-это весь смысл упражнения, но вот подсказка. Вы, вероятно, захотите комбинацию find_last_of и replace.


вот несколько советов. У вас уже введено имя файла - то, что вы хотите сделать, это получить часть имени файла, которая не включает расширение:

std::string basename(const std::string &filename)
{
  // fill this bit in
}

написав эту функцию, вы можете использовать ее для создания имени нового файла:

std::string codeFile = basename(filename) + ".code";
outFile.open(codeFile);

псевдо код будет делать что-то вроде

outFilename = filename;
<change outFilename>
outfile.open(outFilename);

для изменения outFilename посмотрите на strrchr и strcpy в качестве отправной точки (возможно, более подходящие методы-это будет отлично работать с char*)


в Windows (по крайней мере) вы можете использовать _splitpath чтобы рассечь базовое имя из остальных частей, а затем собрать их с помощью вашего любимого форматера строк.


почему бы не использовать метод String find_last_of() ?

std::string new_filename = filename;
size_type result = new_filename.find_last_of('.');

// Does new_filename.erase(std::string::npos) working here in place of this following test?
if (std::string::npos != result)
    new_filename.erase(result);

// append extension:
filename.append(".code");

Я бы просто дописать ".код " к имени файла, введенному пользователем. Если они вошли в "тест".txt", то выходной файл будет " тест.формат txt.код." Если они ввели имя файла без расширения, например "test", то выходной файл будет " test.код."

Я использую этот метод все время с программами, которые генерируют выходные файлы и какой-то связанный вход/диагностический выход. Это просто реализовать и, на мой взгляд, делает отношения между файлами намного больше явный.


Как насчет использования strstr:

char* lastSlash;
char* newExtension = ".code";
ChangeFileExtension(char* filename) {
    lastSlash = strstr(filename, ".");
    strcpy(lastSlash, newExtension);
}

size_t pos = filename.rfind('.');
if(pos != string::npos)
    filename.replace(pos, filename.length() - pos, ".code");
else
    filename.append(".code");

вам нужно скопировать исходное имя файла в новую переменную, где вы можете изменить расширение. Что-то вроде этого:--3-->

string outFilename;
size_t extPos = filename.rfind('.');
if (extPos != string::npos)
{
    // Copy everything up to (but not including) the '.'
    outFilename.assign(filename, 0, extPos);
    // Add the new extension.
    outFilename.append(".code");
    // outFilename now has the filename with the .code extension.
}

возможно, вы можете использовать переменную "filename", если вам не нужно сохранять исходное имя файла для последующего использования. В этом случае вы можете просто использовать:

size_t extPos = filename.rfind('.');
if (extPos != string::npos)
{
    // Erase the current extension.
    filename.erase(extPos);
    // Add the new extension.
    filename.append(".code");
}

ключ должен посмотреть на определение класса строк C++ и понять, что делает каждая функция-член. Использование rfind будет искать назад через строку, и вы не случайно нажмете какие-либо расширения в именах папок, которые могут быть частью исходного имени файла (например, "C:\MyStuff - ... Школа\MyFile.формат txt.)" При работе с смещениями от find, rfind и т. д., вы также захотите использовать их правильно при передаче их в качестве подсчетов другим методам(например, вы используете assign(filename, 0, extPos-1), assign(filename, 0, extPos), assign (filename, 0, extPos+1)).

надеюсь, что это поможет.


Очень Просто:

string str = "file.ext";

str[str.size()-3]='a';
str[str.size()-2]='b';
str[str.size()-1]='c';

cout<<str;

результат: "папка.abc"