本程式設計的目標是根據使用者在命令列中提供的參數,對指定的檔案進行多種內容修改操作。具體需求包括:
+"字串"
:在檔案每一行前加上指定的字串。"字串"+
:在檔案每一行末尾加上指定的字串。-+" 'A字串' ,'B字串' "
:找到每行中的A字串並替換為B字串。new
。程式首先需要解析從命令列接收到的參數,辨識每個參數的類型並存儲相應的操作。
根據需求,命令列參數的格式有以下幾種:
+"字串"
:表示在每行前加上字串
。"字串"+
:表示在每行末尾加上字串
。-+" 'A字串' ,'B字串' "
:表示將每行中的A字串
替換為B字串
。針對不同的參數模式,程式需辨識並存儲相應的操作類型和參數內容。
程式需要打開指定的檔案,逐行讀取內容,根據解析出的操作進行修改,並將結果寫入新檔案。
使用ifstream
進行檔案讀取,ofstream
進行檔案寫入。需檢查檔案是否成功開啟,並處理可能的錯誤。
利用std::getline
逐行讀取檔案內容,並對每行應用解析出的操作。
根據需求,可以先應用前綴、後綴操作,再進行字串替換,或根據使用者需求調整執行順序。
程式需提供詳細的錯誤訊息,如檔案無法開啟、參數格式錯誤等,並在操作完成後告知使用者結果。
以下是滿足上述需求的完整C++程式碼:
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <cstdlib>
// 定義操作類型
enum class OperationType { PREFIX, SUFFIX, REPLACE };
// 結構體存儲操作
struct Operation {
OperationType type;
std::string str1; // 前綴/後綴字串 或 替換操作中的搜尋字串
std::string str2; // 替換操作中的替換字串(前綴/後綴不使用)
};
// 去除字串前後空白
std::string trim(const std::string &s) {
size_t start = s.find_first_not_of(" \t\r\n");
if(start == std::string::npos) return "";
size_t end = s.find_last_not_of(" \t\r\n");
return s.substr(start, end - start + 1);
}
// 解析單個參數,回傳對應的 Operation 物件
bool parseOperation(const std::string& arg, Operation &op) {
// 前綴操作
if(arg.front() == '+' && arg.size() >= 3) {
std::string content = arg.substr(1);
if(content.front() == '"' && content.back() == '"') {
content = content.substr(1, content.size() - 2);
}
op.type = OperationType::PREFIX;
op.str1 = content;
return true;
}
// 後綴操作
if(arg.back() == '+' && arg.size() >= 3) {
std::string content = arg.substr(0, arg.size() - 1);
if(content.front() == '"' && content.back() == '"') {
content = content.substr(1, content.size() - 2);
}
op.type = OperationType::SUFFIX;
op.str1 = content;
return true;
}
// 替換操作
if(arg.find("-+") == 0 && arg.size() >= 6) {
size_t firstQuote = arg.find("'", 2);
size_t secondQuote = arg.find("'", firstQuote + 1);
size_t thirdQuote = arg.find("'", secondQuote + 1);
size_t fourthQuote = arg.find("'", thirdQuote + 1);
if(firstQuote == std::string::npos || secondQuote == std::string::npos ||
thirdQuote == std::string::npos || fourthQuote == std::string::npos) {
return false;
}
std::string findStr = arg.substr(firstQuote + 1, secondQuote - firstQuote - 1);
std::string replaceStr = arg.substr(thirdQuote + 1, fourthQuote - thirdQuote -1);
op.type = OperationType::REPLACE;
op.str1 = findStr;
op.str2 = replaceStr;
return true;
}
return false;
}
int main(int argc, char* argv[]) {
if(argc < 2) {
std::cerr << "用法: " << argv[0] << " 檔名 [操作參數...]" << std::endl;
return EXIT_FAILURE;
}
std::string filename = argv[1];
std::string outFilename = filename + "new";
// 解析操作參數
std::vector<Operation> operations;
for(int i = 2; i < argc; ++i) {
std::string arg = argv[i];
Operation op;
if(!parseOperation(arg, op)) {
std::cerr << "無法解析的參數:" << arg << std::endl;
return EXIT_FAILURE;
}
operations.push_back(op);
}
// 開啟檔案
std::ifstream infile(filename);
if(!infile) {
std::cerr << "無法開啟檔案:" << filename << std::endl;
return EXIT_FAILURE;
}
std::ofstream outfile(outFilename);
if(!outfile) {
std::cerr << "無法建立檔案:" << outFilename << std::endl;
return EXIT_FAILURE;
}
std::string line;
while(std::getline(infile, line)) {
// 依序套用每個操作
for(auto &op : operations) {
if(op.type == OperationType::PREFIX) {
line = op.str1 + line;
}
else if(op.type == OperationType::SUFFIX) {
line = line + op.str1;
}
else if(op.type == OperationType::REPLACE) {
size_t pos = 0;
while((pos = line.find(op.str1, pos)) != std::string::npos) {
line.replace(pos, op.str1.length(), op.str2);
pos += op.str2.length();
}
}
}
outfile << line << "\n";
}
infile.close();
outfile.close();
std::cout << "檔案修改完成,輸出檔案:" << outFilename << std::endl;
return EXIT_SUCCESS;
}
程式透過迴圈遍歷所有命令列參數,並根據第一個字元或最後一個字元判斷參數類型:
+
開頭:視為前綴操作,將指定字串加在每行前面。+
結尾:視為後綴操作,將指定字串加在每行末尾。-+
開頭且包含兩個單引號:視為替換操作,將每行中的A字串替換為B字串。程式開啟指定的輸入檔案,並創建一個新的輸出檔案。逐行讀取輸入檔,每行根據解析出的操作進行修改,最後將結果寫入新檔案。
使用std::ifstream
和std::ofstream
來讀取和寫入檔案,並且在開啟檔案後立即檢查是否成功,以避免後續錯誤。
利用std::getline
方法逐行讀取輸入檔案,每行內容存儲在變數line
中。然後依序套用所有解析出的操作:
PREFIX
:在line
前面加上str1
。SUFFIX
:在line
後面加上str1
。REPLACE
:使用std::string::replace
方法將str1
替換為str2
。修改後的每行內容會立即寫入到新的輸出檔案中,確保處理過程中不會佔用過多記憶體。
程式在解析參數和開啟檔案時會檢查可能的錯誤,並提供有意義的錯誤訊息給使用者,提升程式的健壯性和易用性。
以下表格展示了不同類型參數下,程式對檔案內容的修改效果:
操作參數 | 原始行內容 | 修改後行內容 |
---|---|---|
+"Hello " |
World | Hello World |
" World"+ |
Hello | Hello World |
-+" 'old', 'new' " |
This is old data. | This is new data. |
多重參數:+"Start " " End"+ -+" 'foo', 'bar' " |
foo example | Start bar example End |
為了提升程式的擴展性,可以考慮以下幾點:
對於大型檔案處理,以下優化措施可以提高程式效率:
完善錯誤處理機制,確保程式在遇到異常情況時能夠穩定運行:
try-catch
塊捕捉可能的例外情況。
本程式展示了如何使用C++結合命令列參數靈活地對檔案內容進行多種操作。通過合理的參數解析和高效的檔案處理機制,使用者能夠方便地對檔案進行前綴、後綴添加以及字串替換等操作。未來的優化可集中在提升擴展性、性能以及錯誤處理能力,進一步提升程式的實用性和穩定性。