2009-04-16 139 views
8

好的,這裏是交易,我在我的大學介紹了C++類,並且無法找出如何更改文件的擴展名。首先,我們應該做的是讀取一個.txt文件,並計算單詞,句子,元音等。我得到了這個,但下一步是什麼讓我感到困擾。然後,我們假設使用與輸入文件相同的文件名創建一個新文件,但擴展名爲.code而不是.txt(在該新文件中,我們將通過爲每個ASCII碼添加隨機數來對字符串進行編碼字符,如果你有興趣)。作爲編程的初學者,我不太清楚如何做到這一點。我用下面這段代碼在第一次獲得輸入文件:如何更改存儲在C++字符串中的文件擴展名?

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

我假設創建一個新的文件,我將使用類似:

outfile.open("test.code"); 

但是我不會知道文件名是什麼,直到用戶輸入它,所以我不能說「test.txt」。因此,如果有人知道如何在創建新文件時更改該擴展名,我將非常感激!

回答

8

這有幾種方法。

你可以採取超級懶惰的方法,讓他們只輸入文件名,而不是.txt擴展名。在這種情況下,您可以附加.txt來打開輸入文件。

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

然後你只需要調用

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

下一個辦法是把整個文件名包括擴展名,而只是追加.CODE它,因此你必須test.txt.code。

如果這是可以接受的,這有點含糊不清。

最後,您可以使用std::string方法findreplace來獲取沒有擴展名的文件名,並使用它。

+0

好吧,我認爲在我們剛剛瞭解到字符串方法時,選項更符合我期待的內容。感謝您的輸入! – 2009-04-16 20:53:10

+2

更好的rfind(),因爲它會找到最後一個「。」。而不是'a.b.c.txt'是有效文件名的情況下的第一個 – 2009-04-16 21:05:53

+1

.open()不幸的是,需要一個const char *,而不是std :: sting。 – MSalters 2009-04-17 13:46:38

3

以下是一些提示。已經輸入一個文件名 - 你想要做的就是讓不包括擴展名的文件名的一部分:

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

寫好該功能,你可以用它來創建新的名稱文件:

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

不要忘記測試。我喜歡命名我的files.like.this – veefu 2009-04-16 20:50:42

0

僞代碼會做這樣的事情

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

對於改變outFilename,在strrchr和strcpy爲出發點看(可能是更合適的方法 - 這將工作與char *很好)雖然)

+0

爲什麼在C++代碼時提示C風格的方法? – 2009-04-17 07:47:23

4

不要放棄它,因爲學習是整個練習的重點,但這裏有一個提示。 您可能需要find_last_ofreplace的組合。

-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))。

希望有所幫助。

+3

由於這是一個作業問題,請不要放棄所有內容 – 2009-04-16 20:52:01

8

當然,如果這不是家庭作業,而是一個真實世界的項目,你可能會自己 - 以及其他人閱讀你的代碼 - 通過使用Boost.Filesystemreplace_extension()而不是滾動你自己。沒有足夠簡單的功能,至少在某些角落情況下,您不能提出錯誤。

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"); 
0

在Windows(至少),你可以使用_splitpath從片的其他解剖的基本名稱,然後用你喜歡的字符串格式化重新組合。

0

如何使用的strstr:

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

我只想追加 「.CODE」 到用戶輸入的文件名。如果他們輸入「test.txt」,那麼輸出文件將是「test.txt.code」。如果他們輸入了一個沒有擴展名的文件名,比如「test」,那麼輸出文件就是「test.code」。

我一直在使用這種技術來生成輸出文件和某種相關的日誌/診斷輸出。這很容易實現,並且在我看來,使得文件之間的關係更加明確。

5

我偶爾會問自己這個問題,並在此頁上結束了,所以以供將來參考,這裏是單行語法:

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