[英]How to convert C style printf to C++ style cout in vim
我交出了一些遗留代码,首先我想知道是否可以改变类似的东西
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替换它。 请指教。
你可以试着写一个宏。
首先,一个宏将“%[insert here]”转换为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。 这是在不同缩进级别的情况下。 我们将定位于printf
中的p
。 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的力量。
这实际上比看起来更难,特别是如果你有更复杂的格式与字段宽度说明符或其他类似的东西,或更糟糕的"%["
格式。 如果格式字符串的参数比简单变量或文字更复杂,例如,如果您有函数调用,那么它也很复杂。
但是对于简单的格式化字符串和参数,例如问题中显示的printf
调用,在脚本语言中并不难。 您获取格式化字符串并将其放在字符串变量中,然后获取所有参数并将它们作为字符串放在另一个变量中。 在逗号上拆分参数字符串,并且您有一个参数列表。
然后迭代格式化字符串,当你点击一个'%'
字符,后面没有另一个'%'
字符,然后打印格式化字符串直到那一点,并从参数列表中获取第一个参数。 然后继续扫描格式化字符串,并在单击格式化序列时从其列表中获取每个对应的参数。
我匹配了%d\\n"
在捕获之外并在替换中添加了空格和结束”。
:%s/printf(\(.*\) \S\+, \(.*\));/std::cout << \1 " << \2 << std::endl;/g
答案需要更通用! 因此,我们可以使用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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.