13

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

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

我假设创建一个新文件,我将使用如下内容:

outfile.open("test.code");

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

4

13 回答 13

23

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

string newfilename=filename.substr(0,filename.find_last_of('.'))+".code";
于 2015-01-06T10:05:22.647 回答
9

有几种方法可以解决这个问题。

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

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

然后你只需打电话

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

下一种方法是获取包括扩展名在内的整个文件名,然后将 .code 附加到它上面,这样你就有了 test.txt.code。

这是否可以接受有点模棱两可。

最后,您可以使用std::stringmethods find,并replace获取没有扩展名的文件名,然后使用它。

于 2009-04-16T20:44:46.297 回答
9

当然,如果这不是家庭作业而是一个真实世界的项目,那么您可能会通过使用Boost.Filesystem而不是自己动手来帮自己 - 以及其他阅读您的代码的人 - 一个忙replace_extension()。至少在某些极端情况下,没有任何功能足够简单以至于您无法提出错误。

于 2009-04-16T20:50:46.687 回答
4

不要放弃它,因为学习是练习的重点,但这里有一个提示。您可能需要find_last_of和的组合replace

于 2009-04-16T20:42:55.693 回答
3

这里有一些提示。您已经输入了一个文件名 - 您想要做的是获取不包含扩展名的文件名部分:

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

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

std::string codeFile = basename(filename) + ".code";
outFile.open(codeFile);
于 2009-04-16T20:41:42.730 回答
0

伪代码会做类似的事情

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

要更改 outFilename,请以 strrchr 和 strcpy 为起点(可能是更合适的方法——尽管这对 char* 非常有用)

于 2009-04-16T20:42:39.047 回答
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");
于 2009-04-16T20:53:01.050 回答
0

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

于 2009-04-17T02:44:08.070 回答
0

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

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

于 2012-05-11T10:33:45.713 回答
0

如何使用strstr:

char* lastSlash;
char* newExtension = ".code";
ChangeFileExtension(char* filename) {
    lastSlash = strstr(filename, ".");
    strcpy(lastSlash, newExtension);
}
于 2012-05-11T07:51:56.953 回答
-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.
}

如果您不需要保留原始文件名以供以后使用,则可以使用“文件名”变量。在这种情况下,您可以使用:

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 (文件名,0,extPos),分配(文件名,0,extPos+1))。

希望有帮助。

于 2009-04-16T20:50:40.337 回答
-1
size_t pos = filename.rfind('.');
if(pos != string::npos)
    filename.replace(pos, filename.length() - pos, ".code");
else
    filename.append(".code");
于 2016-06-14T11:59:26.083 回答
-1

很容易:

string str = "file.ext";

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

cout<<str;

结果:“file.abc”

于 2018-05-19T21:17:53.140 回答