繁体   English   中英

如何在Cim中将C风格的printf转换为C ++风格的cout

[英]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的作用是什么

  1. 0f%转到该行的开头,找到第一个百分号(假设%没有以任何其他方式使用,遗憾的是)
  2. 2xmc删除%d部分,然后将当前位置存储在标记c的行中。
  3. f"f,找到字符串的结尾,然后找到第一个逗号。
  4. dwdw删除逗号,然后删除变量名。 这将允许存储变量,以便稍后粘贴。
  5. [backtick]c转到标记c处的行中的存储位置。
  6. i" << ^[插入" <<进入字符串并退回到命令模式。
  7. 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
  1. 0tr转到行首,找到UNTIL first r。 这是在不同缩进级别的情况下。 我们将定位于printf中的p
  2. cwcout << ^[ printf更改为cout <<并转到命令模式。
  3. f(x找到(printf(并删除它)。
  4. $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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM