我需要能够将两个不同的 Windows 路径(它们都可能是相对的)组合成一个路径(通过将第二个应用为第一个的扩展)。文件系统上是否实际存在这两个路径无关紧要。示例:
C:\abc + def -> C:\abc\def
C:\abc + ..\def -> C:\def
\\server\share + def -> \\server\share\def
..\some\path\abc + ..\def -> ..\some\path\def
..\some\path + ..\..\..\def -> ..\..\def
理想情况下,它还应该将驱动器相关的“绝对”路径(即以单个反斜杠开头的路径)解析为给定驱动器上的适当路径:
C:\abc + \def -> C:\def
最后,如果它通过返回绝对路径来处理第二个路径是绝对路径的情况,那就太好了:
C:\abc + D:\def -> D:\def
另一种表达方式是:
我想要一个将路径“A”和路径“B”作为参数的函数。输出“C”应该与我先用 A 调用 SetCurrentDirectory 然后用 B 然后调用 GetCurrentDirectory 相同(但是,路径是否不应该无关紧要'存在,它不应该改变当前的工作目录,如果 A 和 B 都是相对路径,结果应该是相对路径;我并不特别关心结果路径是否包含“..”段)。
代码需要在 Windows 7 上运行。我查看了 shell path handling functions在 Windows API 中,但它们似乎不合适:
PathAppend ,第一个路径不能是相对的:
The path supplied in pszPath cannot begin with "..\" or ".\" to produce a relative path string. If present, those periods are stripped from the output string.
PathCombine ,第一个路径不能是相对路径,也不能是 UNC 路径:
The directory path should be in the form of A:,B:, ..., Z:
(编辑:仔细检查后,该文档片段似乎可能真的属于另一个函数。提到的参数名称与方法签名中给出的参数名称不同。在事实上,正如下面第二个答案所示,PathCombine 似乎确实适用于 UNC 路径。但是,它与 PathAppend 存在同样的问题 - 因为它去除了前导 .. 来自输出路径的片段)。
是否有任何我忽略的标准函数,或者是否有任何库可以正确处理所有情况,包括 UNC 样式路径?或者至少有一种简单的方法可以使用其他已经可用的方法来实现满足我要求的功能?
最佳答案
#include <stdio.h>
#include <stdlib.h>
#ifndef MAX_PATH
#define MAX_PATH 260
#endif
char *rootFolder(char *folder);
int IsFullPath(const char *p){
if(p && *p){
if(((*p>='A') && (*p<='Z')) ||((*p>='a') && (*p<='z'))){
return p[1]==':';
}
return *p=='\\' & p[1]=='\\';
}
return 0;
}
/*_______________________________________________________
*/
char *FolderUp(char *path,int deep){
path=rootFolder(path);
if(!*path) return path;
int i=strlen(path);
char *p=path;
if(path[i-1]=='\\') path--;
while(i &&(deep>0)){
i--;
if(path[i]=='\\'){
p=&path[i+1];
deep--;
}
}
return p;
}
/*_________________________________________________________________
*/
char *NextFolder(char *path){
while(*path){
path++;
if(*path=='\\'){
path++;
break;
}
}
return path;
}
/*_________________________________________________________________
*/
char *rootFolder(char *folder){
char *p;
if((*folder=='\\') && (folder[1]=='\\')){
return NextFolder(&folder[2]);
}
if(*folder && folder[1]==':' && folder[2]=='\\')
return &folder[3];
return folder;
}
int chdir(/*IN_OUT*/char *curDir,const /*IN*/char *newDir){
int deep=0,i;
const char *p=newDir,*tmp;
if(!newDir ||!*newDir ) return 0;
if(IsFullPath(newDir)){
strcpy(curDir,newDir);
return 1;
}
if(*newDir=='\\'){
tmp=rootFolder(curDir);
if(*tmp!='\\') tmp--;
strcpy(tmp,newDir);
return 1;
}
/**/
while(*p && (p[0]=='.' && p[1]=='.')) {
if(p[2]!='\\') {
deep=0;
break;
}
p+=3;
deep++;
}
if(deep){
tmp=FolderUp(curDir,deep);
if(tmp[-1]!='\\') p--;
strcpy(tmp,p);
return 1;
}
i=strlen(curDir);
if(i && curDir[i-1]!='\\'){
curDir[i]='\\';
curDir[i+1]=0;
}
strcat(curDir,newDir);
return 1;
/**/
}
void DoTest(char *curDir,char *newDir){
char path[MAX_PATH];
strcpy(path,curDir);
if(chdir(path,newDir))
printf("'%s' + '%s' -> %'%s'\n",curDir,newDir,path);
else
printf("Error: an unhandled error occured\n");
return ;
}
int main(){
DoTest("C:\\abc","def");
DoTest("C:\\abc","..\\def");
printf("\n");
DoTest("C:\\abc\\","def");
DoTest("C:\\abc\\","..\\def");
printf("\n");
DoTest("\\\\server\\share","def");
DoTest("\\\\server\\share","..\\def");
printf("\n");
DoTest("\\\\server\\share\\","def");
DoTest("\\\\server\\share\\","..\\def");
printf("\n");
DoTest("\\\\server","def");
DoTest("\\\\server","..\\def");
printf("\n");
DoTest("\\\\server\\","def");
DoTest("\\\\server\\","..\\def");
printf("\n");
DoTest("c:\\Folder","\\\\server\\share");
DoTest("\\\\server\\share","c:\\Folder");
printf("\n");
DoTest("..\\Folder\\sub folder","..\\sibling");
printf("\n");
return 0;
}
这是输出:
'C:\abc' + 'def' -> 'C:\abc\def'
'C:\abc' + '..\def' -> 'C:\def'
'C:\abc\' + 'def' -> 'C:\abc\def'
'C:\abc\' + '..\def' -> 'C:\def'
'\\server\share' + 'def' -> '\\server\share\def'
'\\server\share' + '..\def' -> '\\server\def'
'\\server\share\' + 'def' -> '\\server\share\def'
'\\server\share\' + '..\def' -> '\\server\def'
'\\server' + 'def' -> '\\server\def'
'\\server' + '..\def' -> '\\server\def'
'\\server\' + 'def' -> '\\server\def'
'\\server\' + '..\def' -> '\\server\def'
'c:\Folder' + '\\server\share' -> '\\server\share'
'\\server\share' + 'c:\Folder' -> 'c:\Folder'
'..\Folder\sub folder' + '..\sibling' -> '..\Folder\sibling'
关于windows - 当两个路径可能是相对路径时,将路径与 Windows API 组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33150102/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m
如何使此根路径转到:“/dashboard”而不仅仅是http://example.com?root:to=>'dashboard#index',:constraints=>lambda{|req|!req.session[:user_id].blank?} 最佳答案 您可以通过以下方式实现:root:to=>redirect('/dashboard')match'/dashboard',:to=>"dashboard#index",:constraints=>lambda{|req|!req.session[:user_id].b
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
我从用户Hirolau那里找到了这段代码:defsum_to_n?(a,n)a.combination(2).find{|x,y|x+y==n}enda=[1,2,3,4,5]sum_to_n?(a,9)#=>[4,5]sum_to_n?(a,11)#=>nil我如何知道何时可以将两个参数发送到预定义方法(如find)?我不清楚,因为有时它不起作用。这是重新定义的东西吗? 最佳答案 如果您查看Enumerable#find的文档,您会发现它只接受一个block参数。您可以将它发送两次的原因是因为Ruby可以方便地让您根据它的“并行赋
我需要根据字符串路径的长度将字符串路径数组转换为符号、哈希和数组的数组给定以下数组:array=["info","services","about/company","about/history/part1","about/history/part2"]我想生成以下输出,对不同级别进行分组,根据级别的结构混合使用符号和对象。产生以下输出:[:info,:services,about:[:company,history:[:part1,:part2]]]#altsyntax[:info,:services,{:about=>[:company,{:history=>[:part1,:pa