g++;在python中-无法传递包含各种字符的宏

g++;在python中-无法传递包含各种字符的宏,python,c++,macros,g++,Python,C++,Macros,G++,在我的djangopython项目中,我曾经通过g++调用我的C++脚本: os.system('g++ -std=c++0x mutualcepepe.cpp -D "threshold = ' + str(thresh) + '" -o mutualout') “thresh”是一个简单的浮动变量。它工作了,但是整个项目的想法有点改变,现在我想传递一个包含不同字符的字符串,比如说“类型”。 我将在示例中显示我的问题,在本例中,我的宏“djangName”(不再是“阈值”)是“>gi | 1

在我的
django
python项目中,我曾经通过
g++
调用我的
C++
脚本:

os.system('g++ -std=c++0x mutualcepepe.cpp -D "threshold = ' + str(thresh) + '" -o mutualout')
“thresh”是一个简单的浮动变量。它工作了,但是整个项目的想法有点改变,现在我想传递一个包含不同字符的字符串,比如说“类型”。 我将在示例中显示我的问题,在本例中,我的宏“djangName”(不再是“阈值”)是“>gi | 111>gi | 222>gi | 333>gi | 444”。 调用:

os.system('g++ -std=c++0x mutualcepepe.cpp -D "djangoname = ' + str(filename2only) + '" -o mutualout')
终端中出现的错误:

mutualcepepe.cpp: In function ‘int main(int, char**)’:
<command-line>: 0:14: error: expected primary-expression before ‘>’ token
mutualcepepe.cpp: 
99:30: note: in expansion of macro ‘djangoname’ string filename
to_string(djangoname);
                          ^

<command-line>:0:15: error: ‘gi’ was not declared in this scope
mutualcepepe.cpp:99:30: note: in expansion of macro ‘djangoname’
string filename = to_string(djangoname);
mutualcepe.cpp:在函数“int main(int,char**)”中:
:0:14:错误:应在“>”标记之前使用主表达式
mutualcepe.cpp:
99:30:注意:在宏“djangName”字符串文件名的扩展中
to_字符串(djangoname);
^
:0:15:错误:“gi”未在此作用域中声明
mutualcepe.cpp:99:30:注意:在宏'djangName'的扩展中
字符串文件名=to_字符串(djangName);
我认为关键是,当g++编译器“读取”宏包含的内容时,它会对它进行某种除法,当它获得特殊字符时,或者当它读取字母后的数字时,因为在这之后它将其视为整数而不是字符串数据。所以我的问题是,是否有可能以g++编译器运行时不会出现问题的方式传入包含“不同类型”字符的宏(或无论如何是“字符串变量”

我想知道翻译中的一些“不方便”的字符,并把它们放回C++脚本中,但是我不能确定我的宏将包含什么,这取决于使用我的网络应用程序的用户。 老实说,我有一个想法来避免它,但它是完全愚蠢的,与毫无意义地打开新文件和阅读他们需要时间


也许我错了,而且问题的性质不同,我希望您能帮助我或给出有用的建议。

您必须将宏显式地设置为字符串,例如

os.system('g++ ... -Ddjangoname="' + ... + '" ...')
注意双引号的位置。

os.system('g++…')
不会直接启动g++进程。它实际上启动任何配置为默认shell的程序(例如/bin/sh),然后由shell解释命令行

为了避免这种不必要的麻烦及其复杂性,可以使用Python的subprocess.Popen及其communicate()方法直接执行g++。这允许您将命令行参数作为数组传递

例如:

import sys, subprocess
filename2only = '">gi|111>gi|222>gi|333>gi|444"'
args = [
    'g++',
    '-std=c++0x', 'mutualcepepe.cpp',
    '-Ddjangoname=' + str(filename2only),
    '-omutualout'
]
p = subprocess.Popen(args=args, bufsize=-1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
sys.stdout.write(stdout)
sys.stderr.write(stderr)
if p.returncode != 0: sys.stderr.write('failed with exit code: ' + str(p.returncode))
这会将一个
-Ddjangoname=“>gi | 111>gi | 222>gi | 333>gi | 444”
选项传递给编译器,这相当于
#define djangoname>gi | 111>gi | 222>gi 333>gi>gi | 444“

请注意,
str(仅限filename2only)
在这种情况下不是绝对必要的,但它具有支持任何类型的值(字符串、int或float)的优良特性

例如,你可以:

filename2only=12.3
通过
-Ddjangoname=12.3
,这相当于
#定义djangoname 12.3

filename2only='abc'
传递
-Ddjangoname=abc
,相当于
#定义djangoname abc

filename2only=''abc'
来传递
-Ddjangoname=“abc”
,这相当于
#定义djangoname“abc”


filename2only=''a\\'b\'c'
传递
-Ddjangoname=“a\'b\'c”
,这相当于
\define djangoname“a\'b\'c”
,即djangoname是字符串文字
a“b”c
,它包含双引号

这个问题与shell或编译器调用无关,尽管我真诚地认为您最好使用不同的方式从python调用编译器,例如
[subprocess
]模块

<>你的C++程序中的某个地方你有:

string filename = to_string(djangoname);
您正在使用
-D
选项有效地插入

#define djangoname >gi|111>gi|222>gi|333>gi|444
在节目开始时。这意味着您的文件名声明将是:

string filename = to_string(>gi|111>gi|222>gi|333>gi|444);
这根本没有意义,既没有C++,也没有我。因此出现了错误消息,表示无法使用
运算符启动表达式


我不认为这是你的意思,但我不知道你真正想做什么。

仍然有相同的错误,我按你说的做了更改,对吗?os.system('g++-std=c++0x mutualcepe.cpp-Ddjangoname=“”+str(仅文件名2)+'-o mutualout')好的,我会尝试将“>”字符翻译成其他字符,可能会有所帮助。我的文件名将包含.fasta格式的核苷酸序列的标题,它们仅以“>”字符开头,除此之外,我还需要对它们进行校验和。如果您想在程序中插入一个字符串常量,您应该在宏中包含双引号,或者使用预处理器stringify操作符生成编译时文字
std:to_string
不是答案。我替换了不简洁的字符(但它不是真的必要),所以字符串看起来像“gi | 111gi | 222gi | 333gi | 444”,当我用双引号调用时,我得到了“g++:错误:=gi | 111gi | 222gi | 333gi 444:没有这样的文件或目录”
-Ddjangoname=“|文件名为|字符串”
。然后只需分配:
stringfilename=djangoname我在C++ C++中准确地捕获宏,并用精确的调用操作系统(G++-STD= C++0x MutualCePEPE.CPP -D DjangnAME= =“A+STR(FielnaMe2OnLe+O'-O-MutualOut)))得到相同的错误:“G++:Grime:G1111GII222GIG33 3GI 444:没有这样的文件或目录“我真的不知道怎么弄清楚……问题是,我这样使用子流程,只是为了“/mutualout”,所以:command=“/mutualout”process=subprocess.Popen(command,stdout=subprocess.PIPE,shell=True)output=process.communicate(),如果我调用os.system(…)如果没有双引号,我会得到与帖子相同的错误,如果使用双引号,我会得到:“g++:error:=gi | 111gi | 222gi | 333gi | 444:没有这样的fi