如何在C ++中更改存储在字符串中的文件扩展名?

时间:2009-04-16 20:34:50

标签: c++ encoding file-extension

好的就是这笔交易,我正在我的大学里介绍C ++课程,并且无法弄清楚如何更改文件的扩展名。首先,我们要做的是在.txt文件中读取并计算单词,句子,元音等等。我得到了这个,但下一步是令我不安的。然后我们假设使用与输入文件相同的文件名创建一个新文件,但扩展名为.code而不是.txt(在新文件中,我们将通过在每个ASCII码中添加随机数来对字符串进行编码你感兴趣的角色)。作为编程的初学者,我不太清楚如何做到这一点。我正在使用以下代码来获取输入文件:

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

我假设要创建一个新文件,我将使用类似的东西:

outfile.open("test.code");

但是在用户输入之前我不知道文件名是什么,所以我不能说“test.txt”。因此,如果有人知道在创建新文件时如何更改该扩展,我将非常感激!

13 个答案:

答案 0 :(得分:12)

我偶尔会问自己这个问题并最终在这个页面上,所以为了将来参考,这里是单行语法:

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

答案 1 :(得分:9)

有几种方法。

您可以采用超级懒惰的方法,让它们只输入文件名,而不是.txt扩展名。在这种情况下,您可以将.txt附加到它以打开输入文件。

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

然后你打电话

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

接下来的方法是获取整个文件名,包括扩展名,然后只附加.code,这样你就有了test.txt.code。

如果这是可以接受的话,这有点模棱两可。

最后,您可以使用std::string方法findreplace来获取没有扩展名的文件名,并使用它。

答案 2 :(得分:9)

当然,如果这不是家庭作业而是现实世界的项目,你可能会自己 - 以及其他人阅读你的代码 - 使用Boost.Filesystem的{{1而不是滚动自己的。没有足够简单的功能,你无法想出一个bug,至少在某些角落里是这样。

答案 3 :(得分:4)

不要放弃,因为学习是练习的重点,但这是一个暗示。 您可能想要find_last_ofreplace的组合。

答案 4 :(得分:3)

以下是一些提示。您已输入文件名 - 您要做的是获取不包含扩展名的文件名部分:

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

编写该功能后,您可以使用它来创建新文件的名称:

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

答案 5 :(得分:0)

伪代码就是做

之类的事情
outFilename = filename;
<change outFilename>
outfile.open(outFilename);

要更改outFilename,请查看strrchr和strcpy作为起点(可能是更合适的方法 - 虽然可以很好地使用char *)

答案 6 :(得分:0)

为什么不使用字符串方法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");

答案 7 :(得分:0)

在Windows(至少)中,您可以使用_splitpath从其余部分中剖析基本名称,然后使用您喜欢的字符串格式化程序重新组合它们。

答案 8 :(得分:0)

如何使用strstr:

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

答案 9 :(得分:0)

我只是将“.code”附加到用户输入的文件名中。如果他们输入“test.txt”,那么输出文件将是“test.txt.code”。如果他们输入的文件名没有扩展名,比如“test”那么输出文件就是“test.code”。

我一直使用这种技术来生成输出文件和某种相关的日志/诊断输出的程序。它实现起来很简单,在我看来,它使文件之间的关系更加明确。

答案 10 :(得分:0)

AuthnRequest

答案 11 :(得分:-1)

您需要做的是将原始文件名复制到新变量中,您可以在其中更改扩展名。像这样:

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.School \ MyFile.txt”)。当使用find,rfind等的偏移时,你还需要小心地将它们作为计数传递给其他方法时使用它们(例如你使用assign(filename,0,extPos-1),assign (filename,0,extPos),assign(filename,0,extPos + 1))。

希望有所帮助。

答案 12 :(得分:-1)

非常简单:

string str = "file.ext";

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

cout<<str;

结果: &#34; file.abc&#34;