动态增加/删除文件域

 <input   type=button   value="Add"   onclick='additem("tb")'>  
  <table   id="tb"></table>  
  <script   language="javascript">  
  function   additem(id){  
          var   row,cell,str;  
          row   =   eval("document.all["+'"'+id+'"'+"]").insertRow();  
          if(row   !=   null   ){  
                  cell   =   row.insertCell();  
                  str="<input   type="+'"'+"file"+'"'+"   name="+'"'+"addfile"+'"'+"><input   type="+'"'+"button"+'"'+"   value="+'"'+"delete"+'"'+"   onclick='deleteitem(this,"+'"'+"tb"+'"'+");'>"  
                  cell.innerHTML=str;  
          }  
  }  
  function   deleteitem(obj,id){  
          var   rowNum,curRow;  
          curRow   =   obj.parentNode.parentNode;  
          rowNum   =   eval("document.all."+id).rows.length   -   1;  
          eval("document.all["+'"'+id+'"'+"]").deleteRow(curRow.rowIndex);  
  }  
  </script>

下面是你提供的 C++ 程序框架的完整实现。我们将完成以下功能: 1. `ReadFile`:从文件中读取植物信息并构建链表。 2. `InPlant`:判断某个植物名称是否已存在。 3. `InsertPlant`:插入新的植物信息到链表和文件中,若名称已存在则返回 `false`。 我们假设数据文件 `plant.txt` 的格式如下(每条记录占多行): ``` name:银杏 sname:Ginkgo biloba place:中国,日本,韩国 detail:银杏是古老的裸子植物... *** name:玫瑰 sname:Rosa rugosa place:中国,欧洲 detail:玫瑰是常见的观赏植物... *** ``` 使用 `***` 分隔不同植物。 --- ### ✅ 完整代码实现 ```cpp #include <bits/stdc++.h> using namespace std; struct Plant { string name; // 植物名称 string sname; // 学名 vector<string> place; // 分布地(使用vector更灵活) string detail; // 详情描述 }; typedef struct LNode { Plant data; struct LNode* next; } LNode, *LinkList; // 初始化空链表(带头结点) void InitList(LinkList &L) { L = new LNode; L->next = nullptr; } // 从文件中读取数据,存入链表L中 void ReadFile(LinkList &L, string filename) { ifstream inFile(filename); if (!inFile.is_open()) { cout << "无法打开文件 " << filename << endl; return; } InitList(L); // 初始化链表 string line; while (getline(inFile, line)) { if (line.empty()) continue; Plant p; // 读取 name if (line.substr(0, 5) == "name:") { p.name = line.substr(5); } // 读取 sname getline(inFile, line); if (line.substr(0, 6) == "sname:") { p.sname = line.substr(6); } // 读取 place getline(inFile, line); if (line.substr(0, 6) == "place:") { string places = line.substr(6); stringstream ss(places); string city; while (getline(ss, city, ',')) { p.place.push_back(city); } } // 读取 detail getline(inFile, line); if (line.substr(0, 7) == "detail:") { p.detail = line.substr(7); } // 创建新节点插入链表尾部 LNode* newNode = new LNode; newNode->data = p; newNode->next = nullptr; LNode* cur = L; while (cur->next != nullptr) { cur = cur->next; } cur->next = newNode; // 跳过分隔符 *** getline(inFile, line); // 可能是 "***" 或 EOF } inFile.close(); } // 判断该植物名称name是否存在于链表中 int InPlant(LinkList L, string name) { LNode* p = L->next; while (p != nullptr) { if (p->data.name == name) { return 1; } p = p->next; } return 0; } // 增加植物信息:添加到链表和文件末尾 bool InsertPlant(LinkList &L, string filename) { Plant p; cout << "请输入植物名称: "; getline(cin, p.name); // 检查是否已存在 if (InPlant(L, p.name)) { cout << "该植物已存在,无法重复添加!" << endl; return false; } cout << "请输入学名: "; getline(cin, p.sname); cout << "请输入分布地(多个用逗号分隔): "; string placeStr; getline(cin, placeStr); stringstream ss(placeStr); string city; while (getline(ss, city, ',')) { p.place.push_back(city); } cout << "请输入详情描述: "; getline(cin, p.detail); // 写入文件 ofstream outFile(filename, ios::app); // 追加模式 if (!outFile.is_open()) { cout << "无法打开文件进行写入!" << endl; return false; } outFile << "name:" << p.name << endl; outFile << "sname:" << p.sname << endl; string placeLine; for (int i = 0; i < p.place.size(); ++i) { if (i > 0) placeLine += ","; placeLine += p.place[i]; } outFile << "place:" << placeLine << endl; outFile << "detail:" << p.detail << endl; outFile << "***" << endl; outFile.close(); // 插入链表尾部 LNode* newNode = new LNode; newNode->data = p; newNode->next = nullptr; LNode* cur = L; while (cur->next != nullptr) { cur = cur->next; } cur->next = newNode; cout << "植物信息添加成功!" << endl; return true; } ``` --- ### 🔍 代码解释 - **`InitList`**:初始化一个带头结点的单链表,便于操作。 - **`ReadFile`**: - 使用 `ifstream` 打开文件。 - 按行解析每个字段(`name:`、`sname:` 等),提取内容。 - 使用 `stringstream` 和 `,` 分割分布地。 - 每个植物创建一个新节点,插入链表尾部。 - **`InPlant`**:遍历链表,比较 `name` 是否相等。 - **`InsertPlant`**: - 先检查是否已存在。 - 输入所有信息后,以追加方式写入文件。 - 同时插入链表尾部,保持内存与文件同步。 --- ### 🧪 使用示例(main函数参考) ```cpp int main() { LinkList L; ReadFile(L, "plant.txt"); // 测试插入 InsertPlant(L, "plant.txt"); return 0; } ``` 确保项目目录下有 `plant.txt` 文件,或程序会提示无法打开。 --- ### 💡 注意事项 1. **编码问题**:如果使用中文,建议保存文件为 UTF-8 编码,控制台也需支持 UTF-8。 2. **异常处理**:实际应用中应加强输入校验和错误处理。 3. **内存释放**:程序结束前应遍历链表 `delete` 所有节点,防止内存泄漏。 --- ### ✅ 相关优化建议 - 可增加删除、查找、修改功能。 - 可将链表改为双向链表提升效率。 - 可封装成类(如 `PlantManager`)提高可维护性。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值