You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从libssh2_sftp_readdir_ex()输出中提取仅文件与目录名称

最优实现方案(无正则,性能更高,兼容含空格的文件名)

你拿到的每条条目是标准的ls -l格式输出,前8个固定为空格分隔的属性字段(权限、硬链接数、属主、属组、文件大小、月份、日期、时间),从第9个位置开始到行尾的所有内容都是文件名,哪怕文件名本身包含空格也能正确提取。
实现代码如下:

#include <string>
#include <vector>
#include <cctype>

// ... 你的其他业务代码

for (const auto& line : LSEntriesFull) {
    size_t pos = 0;
    int field_count = 0;
    const size_t len = line.size();
    
    // 跳过前8个属性字段
    while (field_count < 8 && pos < len) {
        // 跳过字段前的所有连续空格
        while (pos < len && std::isspace(static_cast<unsigned char>(line[pos]))) {
            pos++;
        }
        // 跳过当前字段的所有非空格内容
        while (pos < len && !std::isspace(static_cast<unsigned char>(line[pos]))) {
            pos++;
        }
        field_count++;
    }
    
    // 跳过文件名前的剩余空格,剩下的内容就是完整文件名
    while (pos < len && std::isspace(static_cast<unsigned char>(line[pos]))) {
        pos++;
    }
    
    if (pos < len) {
        LSEntriesBrief.emplace_back(line.substr(pos));
    }
}

沿用正则写法的修正方案

如果你更习惯用正则实现,可以直接匹配提取文件名部分,不需要拆分所有字段,逻辑更简洁:

#include <regex>
#include <string>
#include <vector>

// ... 你的其他业务代码

// 正则匹配规则:跳过前8个空格分隔的字段后,捕获剩余所有内容为文件名
// 注:用了C++11及以上支持的原始字符串字面量,低版本标准需转义为 "^(?:\\S+\\s+){8}(.+)$"
const std::regex file_name_re(R"(^(?:\S+\s+){8}(.+)$)");
std::smatch match;

for (const auto& line : LSEntriesFull) {
    if (std::regex_match(line, match, file_name_re)) {
        LSEntriesBrief.emplace_back(match[1].str());
    }
}

原代码错误原因

  1. 用空格拆分所有字段后,重复调用itr++会跳过部分字段,还可能出现迭代器越界问题
  2. 没有过滤前8个属性字段,直接把所有拆分后的字段都存入了目标向量
  3. 拆分逻辑无法兼容文件名带空格的场景,会把单个文件名拆成多个错误条目存入

内容的提问来源于stack exchange,提问作者fborges22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 13:36:03