网上找的有bug,自己稍微改了下,简单测试了一下,实际还可以找到各种特例,例如含有特殊字符*、?等
直接上代码
std::string ToAbsolutePath(std::string input_path)
{
if (input_path.length() == 0)
{
return "";
}
if (input_path[0] == '.')
{
char buff[FILENAME_MAX]; //create string buffer to hold path
_getcwd(buff, FILENAME_MAX);
input_path = std::string(buff) + "/" + input_path;//以相对路径
}
//路径字符规范化
const std::string old_value = "\\";
const std::string new_value = "/";
for (std::string::size_type pos(0); pos != std::string::npos; pos += new_value.length())
{
if ((pos = input_path.find(old_value, pos)) != std::string::npos)
{
input_path.replace(pos, old_value.length(), new_value);
}
else
{
break;
}
}
//路径拆分
std::vector<std::string> input_path_vec;
std::string str_temp;
size_t i_size = input_path.size();
for (size_t i = 0; i < i_size; ++i)
{
if (input_path[i] != '/')
{
str_temp += input_path[i];
}
else
{
input_path_vec.push_back(str_temp);
str_temp.clear();
}
}
//最后一个路径为目录名或文件名
if (str_temp.length() > 0)
{
input_path_vec.push_back(str_temp);
str_temp.clear();
}
if (input_path_vec.size() == 0)
{
const bool is_windows_path = input_path.find(":") != std::string::npos;
if (is_windows_path)
{
return "";
}
else
{
return "/";
}
}
const std::string first_path = input_path_vec[0];
const bool is_windows_path = first_path.find(":") != std::string::npos;
if (input_path.find("...") != std::string::npos)//错误路径
{
if (is_windows_path)
{
return first_path;
}
else
{
return "/";
}
}
//路径拼接
std::vector<std::string> output_path_vec;
size_t i_vec_size = input_path_vec.size();
for (size_t j = 0; j < i_vec_size; ++j)
{
const std::string &str = input_path_vec[j];
if (str == ".")
{
//不需要拷贝
}
else if (str == "..")
{
if (output_path_vec.size() > 0)//不判断size会导致崩溃
{
output_path_vec.pop_back();
}
}
else{
output_path_vec.push_back(str);
}
}
if (output_path_vec.size() == 0)
{
if (is_windows_path)
{
return first_path;//windows path
}
else
{
return "/";//linux path
}
}
std::string ret_str = output_path_vec[0];
for (size_t i = 1; i < output_path_vec.size(); ++i)
{
ret_str = ret_str + "/" + output_path_vec[i];
}
if (is_windows_path)//windows path
{
if (ret_str.find(":") == std::string::npos)
{
return first_path;//路径有误,返回根目录
}
else
{
return ret_str;
}
}
else
{
return "/" + ret_str;//linux path
}
}