C++ 如何在我的程序中找到“a”;常量字符*+;int";表达

C++ 如何在我的程序中找到“a”;常量字符*+;int";表达,c++,c,migration,vb6-migration,C++,C,Migration,Vb6 Migration,我正在进行源代码迁移,转换程序没有转换嵌入字符串与整数的串联。现在我有很多这样的代码: f("some text" + i); std::string some_str = ...; int i = ...; f(some_str + i); 由于C/C++将其解释为数组下标,f将接收“一些文本”,或“一些文本”,或“我的文本” 我的源语言将字符串与int的串联转换为字符串串联。现在,我需要逐行浏览源代码,并手动将前面的表达式更改为: f("some text" + std::to_str

我正在进行源代码迁移,转换程序没有转换嵌入字符串与整数的串联。现在我有很多这样的代码:

f("some text" + i);
std::string some_str = ...;
int i = ...;

f(some_str + i);
由于C/C++将其解释为数组下标,
f
将接收
“一些文本”
,或
“一些文本”
,或
“我的文本”

我的源语言将字符串与int的串联转换为字符串串联。现在,我需要逐行浏览源代码,并手动将前面的表达式更改为:

f("some text" + std::to_string(i));
转换程序设法将本地“
String
”变量转换为“
std::String
”,从而生成表达式:

f("some text" + i);
std::string some_str = ...;
int i = ...;

f(some_str + i);

这些都很容易修复,因为这样的表达式,C++编译器会输出错误。p>


有没有工具可以在源代码中自动找到这样的表达式?

我不熟悉很多可以这样做的工具,但我认为
grep
在某种程度上是有帮助的

在源代码的根目录中,尝试:

grep -rn '".\+"\s*+\s*' .
,它可以找到所有包含一行的文件,如
“xxxxx”+
,希望这可以帮助您找到所有需要的行

如果所有整数都是常量,则可以将grep表达式更改为:

grep -rn '".\+"\s*+\s*[0-9]*' .
您还可以在字符串常量之前包含
):

grep -rn '(".\+"\s*+\s*[0-9]*' .

这可能不是“正确”的答案,但我希望这能帮助您。

如果您的情况与

"some text in quotations" + a_numeric_variable_or_constant
然后,Powergrep或类似的程序将允许您扫描所有文件以查找

("[^"]+")\s*\+\s*(\w+)
并替换为

\1 + std::to_string(\2)
这将为您带来可能的匹配项,但我强烈建议您首先预览要替换的内容。因为这也将替换字符串变量

正则表达式无法理解代码的语义,因此无法确定它们是否为整数。为此,您需要一个具有类似CDT或静态代码分析器的解析器的程序。但不幸的是,我不知道任何可以做到这一点的程序。总之,我希望正则表达式能够提供帮助:)

PS:在最坏的情况下,如果变量不是数值,那么编译器会给您错误,因为
to_string
函数只接受数值。可能是以后,然后你可以手动更换只有他们,我只能希望不会更多

PS 2:有些人可能认为Powergrep很贵。您可以试用15天,并具有完整的功能。

< P>您可以尝试,一个开源的LICT程序,用于C++开发和在脸谱网上使用。它具有黑名单令牌序列功能(
checkBlacklistedSequences
)。您可以将您的令牌序列添加到
checkBlacklistedSequences
函数中,并且
flint
将报告它们

checkBlacklistedSequences
函数中,我添加了序列
string\u literal+number

BlacklistEntry([tk!"string_literal", tk!"+", tk!"number"],
               "string_literal + number problem!\n",
                true),
然后编译并测试

$ cat -n test.cpp
 1  #include <iostream>
 2  #include <string>
 3  
 4  using namespace std;
 5  
 6  void f(string str)
 7  {
 8      cout << str << endl;
 9  }
10  
11  int main(int argc, char *argv[])
12  {
13      f("Hello World" + 2);
14  
15      f("Hello World" + std::to_string(2));
16  
17      f("Hello World" + 2);
18  
19      return 0;
20  }

$ ./flint test.cpp 
test.cpp(13): Warning: string_literal + number problem!
test.cpp(17): Warning: string_literal + number problem!
$cat-n test.cpp
1#包括
2#包括
3.
4使用名称空间标准;
5.
6空f(字符串str)
7  {

8 CUT

您可能不需要使用C++一个用户定义的转换规则。基本上,您需要将<<代码> f>代码>函数的参数从<代码> const char *//>代码>代码> STD::String 转换为一种类型,它仅从字符串文字( const char)隐式转换。[size]

)或
std::string
实例(在表达式中添加
std::to_string
时得到的内容)

#包括
#包括
结构字符串\u代理
{
std::字符串值;
string_代理(const std::string&value):value(value){}
string_代理(std::string&&value):value(std::move(value)){
模板
string_proxy(const char(&str)[size]):value(str){
};
void f(字符串\u代理)
{

std::cout您可以尝试使用Map Reduce Clang插件。 Google开发的这个工具就是为了进行这种重构,混合了强类型检查和regexp


(参见视频演示)。

简单!只需将所有
+
替换为
-&

find . -name '*.cpp' -print0 | xargs -0 sed -i '' 's/+/-\&/g'

在尝试编译项目时,在其他错误之间,您将看到如下内容:

foo.cpp:9:16: error: 'const char *' and 'int *' are not pointers to compatible types
    return f(s -& i);
             ~ ^~~~
f(std::string("Hello ") + g(i));
(我使用的是clang,但其他编译器也会出现类似的错误)


因此,您只需过滤编译器输出以仅保留这些错误:

clang++ foo.cpp 2>&1 | grep -F "error: 'const char *' and 'int *' are not pointers to compatible types"
你会得到:

foo.cpp:9:16: error: 'const char *' and 'int *' are not pointers to compatible types
foo.cpp:18:10: error: 'const char *' and 'int *' are not pointers to compatible types

可以使用C++类型化的操作符,创建一个新的类,它可以使运算符+重载到您的需要。您可以将int替换为新的类“整数”并执行所需的重载。这不需要在主函数调用中进行更改或字替换。
class Integer{
    long  i;
    std::string formatted;
public:
     Integer(int i){i = i;}
     operator char*(){
        return (char*)formatted.c_str();}
     friend Integer operator +( char* input, Integer t);
};
Integer operator +( char* input, Integer integer) {
    integer.formatted = input + std::to_string(integer.i);
    return integer;
}
Integer i = ....
f("test" + i); //executes the overloaded operator

我找到了一种非常简单的方法来检测这个问题。正则表达式和lint都无法匹配更复杂的表达式,如以下所示:

f("Hello " + g(i));
我需要的是以某种方式进行类型推断,因此我让编译器来进行。使用
std::string
而不是文本字符串会产生错误,因此我需要将所有字符串文本转换为包装的
std::string
版本,如下所示:

foo.cpp:9:16: error: 'const char *' and 'int *' are not pointers to compatible types
    return f(s -& i);
             ~ ^~~~
f(std::string("Hello ") + g(i));
然后,在重新编译项目后,我会看到所有错误。源代码位于GitHub上,包含48行Python代码:


我假设函数f(一些str+i);您的定义应该是这样的

 void f(std::string value)
 {
    // do something.
 }
如果你声明了一些其他类,比如为整数实现操作符+,如果你像下面的代码那样声明你的函数,它将像这个实现f(some_str+i)一样工作


这里是一个示例实现

循环变量呢?比如(x..f(“Hello world”+x);用tk!“identifier”而不是tk!“number”再添加一个序列它是有效的。然而,标识符的类型可以是任何类型。对int没有具体的检查。这看起来非常令人振奋。然而,我要做的是更一般的情况,用const char*和int检测操作符+的每个表达式,因此我想要的是类型推断。我在我的项目中没有使用lint,b