ssh-循环显示数组或者list

本文介绍如何使用Struts2的<s:iterator>标签循环遍历List集合,并展示如何在表格中逐条显示数据。通过设置value属性指定要遍历的List变量名,id属性定义每次迭代的元素引用,status属性提供迭代状态信息。

循环显示数组或者list,value代表list名称,id代表当前迭代的元素,

<s:iterator value="testcaseList"  id="testcase" status="i">
    <tr>
        <td><s:property value="%{#i.index+1}"/></td>
        <td><s:property  value="testcase"/></td>
    </tr>
</s:iterator>
char** filename_completion_matches(const char* text, CPFunction* genfunc) { static int last_index = 0; // 当前循环索引 static char *last_text = NULL; // 上次输入的文本 static char **full_match_list = NULL; // 完整匹配列表缓存 static int full_match_count = 0; // 匹配项总数 // 状态重置:输入变化时重新收集匹配项 if (last_text == NULL || strcmp(text, last_text) != 0) { // 释放旧资源 if (full_match_list) { for (int i = 0; i < full_match_count; i++) { XFREE(MTYPE_TMP, full_match_list[i]); } XFREE(MTYPE_TMP, full_match_list); } if (last_text) XFREE(MTYPE_TMP, last_text); // 初始化新状态 last_index = 0; last_text = XSTRDUP(MTYPE_TMP, text); full_match_list = NULL; full_match_count = 0; // 收集所有匹配项 char **temp_list = NULL; int count = 0; char *match; // 循环调用生成函数直到返回NULL for (int state = 0; (match = (*genfunc)(text, state)) != NULL; state++) { temp_list = XREALLOC(MTYPE_TMP, temp_list, (count + 1) * sizeof(char*)); temp_list[count++] = match; } // 保存结果 full_match_list = temp_list; full_match_count = count; } // 无匹配项时返回NULL if (full_match_count == 0) { return (char**)NULL; } // 计算当前循环位置 int current_index = last_index % full_match_count; // 构建返回列表(单条目) char **result_list = XMALLOC(MTYPE_TMP, 3 * sizeof(char*)); result_list[0] = XSTRDUP(MTYPE_TMP, full_match_list[current_index]); // 公共前缀 result_list[1] = XSTRDUP(MTYPE_TMP, full_match_list[current_index]); // 实际匹配项 result_list[2] = NULL; // 结束标记 // 更新循环索引 last_index = (last_index + 1) % full_match_count; printf("\nfilename_completion_matches: result_list[0] = %s, result_list[1] = %s, result_list[2] = %s\n", result_list[0],result_list[1],result_list[2]); return result_list; } 调用:matches = filename_completion_matches(text, filename_completion_function); 现在filename_completion_function中打印显示能遍历出所有文件,但是filename_completion_matches中的打印显示只能显示出目录的: <dahua>dir e cmlsh_completion: enter------------------ filename_completion_function: temp = etc/ filename_completion_matches: result_list[0] = etc/, result_list[1] = etc/, result_list[2] = (null) cmlsh_completion: matches = etc/ tc/ cmlsh_completion: enter------------------ filename_completion_function: temp = etc/ssh/ filename_completion_function: temp = etc/nos.conf filename_completion_function: temp = etc/nos.conf.bak filename_completion_function: temp = etc/CML_DB.db filename_completion_matches: result_list[0] = etc/ssh/, result_list[1] = etc/ssh/, result_list[2] = (null) cmlsh_completion: matches = etc/ssh/ ssh/ cmlsh_completion: enter------------------ filename_completion_function: temp = etc/ssh/ssh_host_rsa_key.pub filename_completion_function: temp = etc/ssh/ssh_host_ecdsa_key.pub filename_completion_function: temp = etc/ssh/ssh_host_rsa_key filename_completion_function: temp = etc/ssh/ssh_host_ed25519_key.pub filename_completion_function: temp = etc/ssh/ssh_host_ed25519_key filename_completion_function: temp = etc/ssh/ssh_host_ecdsa_key filename_completion_matches: result_list[0] = etc/ssh/ssh_host_rsa_key.pub, result_list[1] = etc/ssh/ssh_host_rsa_key.pub, result_list[2] = (null)
07-25
还是使用 char* filename_completion_function(const char* text, int state) { static DIR* dir = NULL; static char *filename = NULL, *dirname = NULL; static size_t filename_len = 0; struct dirent* entry; char* temp; size_t len; // 状态重置:当state==0时,表示新的补全请求 if (state == 0) { // 释放之前资源(增加空指针检查) if (dir) { closedir(dir); dir = NULL; } if (filename) { XFREE(MTYPE_TMP, filename); filename = NULL; } if (dirname) { XFREE(MTYPE_TMP, dirname); dirname = NULL; } // 解析text,分离目录和文件名部分 const char *temp_ptr = strrchr(text, '/'); if (temp_ptr) { // 提取文件名部分(最后一个斜杠之后的内容) filename = XSTRDUP(MTYPE_TMP, temp_ptr + 1); if (!filename) return NULL; // 提取目录部分(包括最后一个斜杠) len = temp_ptr - text + 1; // 包括斜杠 dirname = XMALLOC(MTYPE_TMP, len + 1); if (!dirname) { XFREE(MTYPE_TMP, filename); return NULL; } strncpy(dirname, text, len); dirname[len] = '\0'; // 确保终止符 } else { // 没有斜杠,说明只有文件名(保持无前缀) filename = XSTRDUP(MTYPE_TMP, text); if (!filename) return NULL; dirname = XSTRDUP(MTYPE_TMP, ""); // 空字符串代替"./" if (!dirname) { XFREE(MTYPE_TMP, filename); return NULL; } } // 处理家目录展开(~user) if (dirname[0] == '~') { char *expanded = tilde_expand(dirname); if (expanded) { XFREE(MTYPE_TMP, dirname); dirname = expanded; } } filename_len = filename ? strlen(filename) : 0; // 打开目录(处理空目录名情况) const char *open_path = (dirname[0] == '\0') ? "." : dirname; dir = opendir(open_path); if (!dir) { XFREE(MTYPE_TMP, filename); XFREE(MTYPE_TMP, dirname); filename = NULL; dirname = NULL; return NULL; } } // 如果目录流未打开或资源未初始化,返回NULL if (!dir || !filename || !dirname) { return NULL; } // 遍历目录,寻找匹配项 while ((entry = readdir(dir)) != NULL) { // 跳过隐藏文件(以.开头),除非文件名以.开头 if (filename[0] != '.' && entry->d_name[0] == '.') { // 但允许匹配显式指定的隐藏文件 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } } // 检查文件名是否匹配 size_t entry_len = strlen(entry->d_name); if (entry_len < filename_len) { continue; } if (strncmp(entry->d_name, filename, filename_len) == 0) { // 计算路径长度(避免空目录名问题) size_t dir_len = strlen(dirname); len = dir_len + entry_len + 2; // +1 for null, +1 for possible '/' temp = XMALLOC(MTYPE_TMP, len); if (!temp) continue; // 分配失败则跳过 // 拼接目录和文件名(处理空目录名) if (dir_len > 0) { snprintf(temp, len, "%s%s", dirname, entry->d_name); } else { strncpy(temp, entry->d_name, len); } // 检查是否为目录(使用d_type优化性能) int is_dir = 0; #if defined(_DIRENT_HAVE_D_TYPE) || defined(__linux__) if (entry->d_type == DT_DIR) { is_dir = 1; } else if (entry->d_type == DT_LNK || entry->d_type == DT_UNKNOWN) { // 需要stat检查 struct stat st; if (stat(temp, &st) == 0 && S_ISDIR(st.st_mode)) { is_dir = 1; } } #else // 没有d_type支持的系统使用stat struct stat st; if (stat(temp, &st) == 0 && S_ISDIR(st.st_mode)) { is_dir = 1; } #endif // 如果是目录,添加斜杠 if (is_dir) { size_t cur_len = strlen(temp); if (cur_len + 1 < len) { temp[cur_len] = '/'; temp[cur_len + 1] = '\0'; } else { // 重新分配以容纳斜杠 char *new_temp = XREALLOC(MTYPE_TMP, temp, cur_len + 2); if (new_temp) { temp = new_temp; strcat(temp, "/"); } } } // 返回当前匹配项 printf("\nfilename_completion_function: temp = %s\n", temp); return temp; } } // 没有更多匹配项,清理资源 closedir(dir); dir = NULL; XFREE(MTYPE_TMP, filename); XFREE(MTYPE_TMP, dirname); filename = NULL; dirname = NULL; return NULL; } 这个filename_completion_function函数不修改 但是上层调用的: char** filename_completion_matches(const char* text, CPFunction* genfunc) { static int last_index = 0; // 当前循环索引 static char *last_text = NULL; // 上次输入的文本 static char **full_match_list = NULL; // 完整匹配列表缓存 static int full_match_count = 0; // 匹配项总数 // 状态重置:输入变化时重新收集匹配项 if (last_text == NULL || strcmp(text, last_text) != 0) { // 释放旧资源 if (full_match_list) { for (int i = 0; i < full_match_count; i++) { XFREE(MTYPE_TMP, full_match_list[i]); } XFREE(MTYPE_TMP, full_match_list); } if (last_text) XFREE(MTYPE_TMP, last_text); // 初始化新状态 last_index = 0; last_text = XSTRDUP(MTYPE_TMP, text); full_match_list = NULL; full_match_count = 0; // 收集所有匹配项 char **temp_list = NULL; int count = 0; char *match; // 循环调用生成函数直到返回NULL for (int state = 0; (match = (*genfunc)(text, state)) != NULL; state++) { // 扩展数组 char **new_list = (char **)XREALLOC(MTYPE_TMP, temp_list, (count + 1) * sizeof(char*)); if (!new_list) { // 分配失败,释放已收集的 for (int i = 0; i < count; i++) { XFREE(MTYPE_TMP, temp_list[i]); } XFREE(MTYPE_TMP, temp_list); return NULL; } temp_list = new_list; temp_list[count] = match; count++; } // 保存结果 full_match_list = temp_list; full_match_count = count; } // 无匹配项时返回NULL if (full_match_count == 0) { return (char**)NULL; } // 计算当前循环位置 int current_index = last_index % full_match_count; last_index = (last_index + 1) % full_match_count; // 构建返回列表(单条目) char **result_list = (char **)XMALLOC(MTYPE_TMP, 3 * sizeof(char*)); if (!result_list) { return NULL; } // 复制匹配项 result_list[0] = XSTRDUP(MTYPE_TMP, full_match_list[current_index]); // 公共前缀 result_list[1] = XSTRDUP(MTYPE_TMP, full_match_list[current_index]); // 实际匹配项 result_list[2] = NULL; // 结束标记 printf("\nfilename_completion_matches: result_list[0] = %s, result_list[1] = %s, result_list[2] = %s\n", result_list[0],result_list[1],result_list[2]); return result_list; } 可能要修改一下 现在的现象是: <dahua>dir e cmlsh_completion: enter------------------ filename_completion_function: temp = etc/ filename_completion_matches: result_list[0] = etc/, result_list[1] = etc/, result_list[2] = (null) cmlsh_completion: matches = etc/, etc/, tc/ cmlsh_completion: enter------------------ filename_completion_function: temp = etc/ssh/ filename_completion_function: temp = etc/nos.conf filename_completion_function: temp = etc/nos.conf.bak filename_completion_function: temp = etc/CML_DB.db filename_completion_matches: result_list[0] = etc/ssh/, result_list[1] = etc/ssh/, result_list[2] = (null) cmlsh_completion: matches = etc/ssh/, etc/ssh/, ssh/ cmlsh_completion: enter------------------ filename_completion_function: temp = etc/ssh/ssh_host_rsa_key.pub filename_completion_function: temp = etc/ssh/ssh_host_ecdsa_key.pub filename_completion_function: temp = etc/ssh/ssh_host_rsa_key filename_completion_function: temp = etc/ssh/ssh_host_ed25519_key.pub filename_completion_function: temp = etc/ssh/ssh_host_ed25519_key filename_completion_function: temp = etc/ssh/ssh_host_ecdsa_key filename_completion_matches: result_list[0] = etc/ssh/ssh_host_rsa_key.pub, result_list[1] = etc/ssh/ssh_host_rsa_key.pub, result_list[2] = (null) cmlsh_completion: matches = etc/ssh/ssh_host_rsa_key.pub, etc/ssh/ssh_host_rsa_key.pub, ssh_host_rsa_key.pub cmlsh_completion: enter------------------ 虽然filename_completion_function函数中的打印temp是能遍历etc下的普通文件和子目录,但是最外边显示的就没有普通文件,哪里还有问题?
最新发布
07-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值