我交出了一些遗留代码,首先我想知道是否可以更改
之类的内容printf("test %d\n", var);
到
std::cout << "test " << var << std::endl;
它们中有很多并且手动完成它们非常耗时。有没有办法使用vim来实现这一目标?
我得到的最远的是
:%s/printf(\(.*\), \(.*\));/std::cout << \1 << \2 << std::endl;/g
但这只会让我
std::cout << "test %d\n" << var << std::endl;
我可以将clang格式应用于代码,因此在printf中我可以保证逗号后总是有空格。在此示例中,空格介于逗号和var之间。
理想情况下,这个vim命令能够检测百分号以了解其中有多少变量,并且还检测\ n以知道何时用std :: endl替换它。请指教。
答案 0 :(得分:1)
这实际上比看起来更难,特别是如果你有更复杂的格式与字段宽度说明符或其他类似的东西,或更糟糕的"%["
格式。如果格式字符串的参数比简单变量或文字更复杂,例如,如果你有函数调用,那么它也很复杂。
但是对于 简单 格式化字符串和参数,例如问题中显示的printf
调用,它并不难做到一种脚本语言。您获取格式化字符串并将其放在字符串变量中,然后获取所有参数并将它们作为字符串放在另一个变量中。在逗号上拆分参数字符串,你有一个参数列表。
然后迭代格式化字符串,当你点击'%'
字符后面没有另一个'%'
字符时,然后打印格式化字符串直到那一点并从中获取第一个参数参数列表。然后继续扫描格式化字符串,并在点击格式化序列时从其列表中获取每个相应的参数。
答案 1 :(得分:1)
我在捕获之外匹配了%d\n"
,并在替换中添加了一个空格和结束。
:%s/printf(\(.*\) \S\+, \(.*\));/std::cout << \1 " << \2 << std::endl;/g
答案 2 :(得分:1)
您可以尝试编写宏。
首先,转换&#34;%[插入此处]&#34;以cout格式。
:reg
--- Registers
"f 0f%2xmcf"f,dwdw`ci" << ^[pa << "^[
那么这对宏键F的作用是
0f%
转到该行的开头,找到第一个百分号(假设%没有以任何其他方式使用,遗憾的是)2xmc
删除%d
部分,然后将当前位置存储在标记c的行中。f"f,
找到字符串的结尾,然后找到第一个逗号。dwdw
删除逗号,然后删除变量名称。这将允许存储变量,以便以后粘贴。[backtick]c
转到标记c。i" << ^[
将" <<
插入字符串并退回到命令模式。pa << "^[
粘贴存储的变量名称,然后插入字符串<< "
。所以,最终的结果就是这个
printf("test %d\n", var); // Before
printf("test " << var << "\n"); // After
在另一个宏键R上,简单地多次重放宏F(比如说100)。如果您的变量少于100个,那么它将无法完成宏,因为f%
将会失败。
:reg
--- Registers
"r 100@f
所以,一个例子是
printf("test %d %d %d %d %d\n", var, var1, var2, var3, var4); // Before
printf("test " << var << " " << var1 << " " << var2 << " " << var3 << " " << var4 << "\n"); // After
现在编写一个宏C来将开始和结束转换为C ++!
:reg
--- Registers
"c 0trcwcout << ^[f(x$F)x
0tr
转到行首,找到UNTIL first r。这是在不同缩进级别的情况下。我们将定位在p
中的printf
。cwcout << ^[
将printf
更改为cout <<
并转到命令模式。f(x
在(
中找到printf(
并将其删除。$F)x
转到该行的末尾,找到最后一个)
并将其删除。这给出了:
printf("test " << var << " " << var1 << " " << var2 << " " << var3 << " " << var4 << "\n"); // Before
cout << "test " << var << " " << var1 << " " << var2 << " " << var3 << " " << var4 << "\n"; // After
要将它们组合在一起,创建另一个宏T,它找到printf
,运行宏C,然后运行宏F.它按此顺序完成,这样如果早期部分失败,其余的命令不会跑。
:reg
--- Registers
"t /printf^M@c@r
运行此宏T 3次会执行以下操作:
// Before
printf("test %d\n", var);
printf("test %d %d %d %d %d\n", var, var1, var2, var3, var4);
printf("test %d %d\n", var, var2);
// After
cout << "test " << var << "\n";
cout << "test " << var << " " << var1 << " " << var2 << " " << var3 << " " << var4 << "\n";
cout << "test " << var << " " << var2 << "\n";
这个解决方案并不完美,它假定百分比没有以任何其他格式使用,并且必须为每个printf手动重复(垃圾邮件@@
)。我希望它至少是有用的,并展示了vim的力量。
答案 3 :(得分:0)
答案需要更通用!
因此,我们可以使用vim函数来检测%
个%d%f%s
字符以及\n\r
之类的转义序列字符。
只是一个样本的伪代码。
:function ConvertToCPP()
:let a = getline('.')
: while a doesn't contain % or \ characters
: take any number of \n and put as endl at end of line, if any
: remove off the % characters.
: put << in between each of them
: call setline ('.', a)
:return 1
:end function
不,你可以用范围来调用这个函数,这样它就可以轻松地替换它们。
:10,20ConvertToCPP()