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

StackOverflow https://stackoverflow.com/questions/757933

  •  09-09-2019
  •  | 
  •  

Вопрос

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

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

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

outfile.open("test.code");

Но я не узнаю имя файла, пока пользователь не введет его, поэтому я не могу сказать «test.txt».Так что, если кто-нибудь знает, как изменить это расширение при создании нового файла, я был бы очень признателен!

Это было полезно?

Решение

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

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

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

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

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

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

Немного двусмысленно, приемлемо это или нет.

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

Другие советы

Иногда я задаю себе этот вопрос и попадаю на эту страницу, поэтому на будущее привожу однострочный синтаксис:

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

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

Не хочу этого выдавать, поскольку в обучении и заключается весь смысл упражнения, но вот подсказка.Вероятно, вам понадобится комбинация 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 чтобы отделить базовое имя от остальных частей, а затем собрать их заново с помощью любимого средства форматирования строк.

почему бы не использовать строковый метод 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");

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

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

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

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

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

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.
}

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

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.School\MyFile.txt»).При работе со смещениями find, rfind и т. д. вам также следует быть осторожными и правильно использовать их при передаче в качестве счетчиков другим методам (например,вы используете назначение (имя файла, 0, extPos-1), назначение (имя файла, 0, extPos), назначение (имя файла, 0, extPos + 1)).

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

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

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

string str = "file.ext";

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

cout<<str;

Результат:"файл.abc"

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top