要从终端呼叫C中的printf("Hello!");
,请使用
echo '#include<stdio.h>
void main()
{
printf("Hello!");
}' > foo.c
然后调用gcc foo.c
进行输出。不幸的是,流水线
echo '#include<stdio.h>
void main()
{
printf("Hello!");
}' | gcc
无法抱怨没有输入文件。最后,我希望有一个脚本,我可以使用command
从终端编译C ./script [command]
。任何建议将不胜感激。
答案 0 :(得分:4)
是的,但您必须使用-x
选项指定语言。使用-xc
将输入文件指定为stdin,将语言指定为C(如果您希望它是C ++,则使用,使用-xc++
)。因此,在您的情况下,命令将是
echo '#include<stdio.h>
void main()
{
printf("Hello!");
}' | gcc -o output.o -xc -
您可以阅读有关Command Line Compiler Arguments的更多信息:请参阅Invoking GCC章节。
然而,正如@Basile所说,不值得努力避免处理C文件。检查他的答案以获取更多信息。
答案 1 :(得分:2)
我过去做过
ln -s /dev/stdin stdin.c
现在stdin.c
是/dev/stdin
的符号链接,即魔术文件&#34;包含&#34;我打字或管道的任何东西。但文件名以.c
结尾,因此任何C编译器都应将其视为C文件。像
(echo '#include <stdio.h>'
echo 'int main(void) { printf("Hello, world!\n"); }') |
cc stdin.c
工作得很好。
(显然,这假设您使用的是具有符号链接和/dev/stdin
的类Unix系统。)
答案 2 :(得分:2)
Other答案解释了如何让gcc
从 stdin 中读取C代码,但请注意在实践中不值得努力避免处理C文件。
(我猜您正在使用某些类似Linux的POSIX操作系统;如果没有,请根据您的操作系统和编译器调整我的答案)
自动发送C代码是常用做法(许多学术编程语言都是compiling to C,许多构建使用生成的C代码,例如来自bison)。但是使用管道和 stdin 没有多大好处,因为C编译器需要花费大量时间(特别是optimization,这是您经常需要的,例如通过编译{{1} })。
所以我的建议是将生成的C代码放在一个真正的文件中(也许是一些临时文件,应该在以后适当删除)。如果磁盘性能存在问题,那么该文件可能位于某个tmpfs文件系统上(实际上它永远不会用于gcc -O2
已编译的源代码),并且该文件可能是临时的(例如,以后删除)想要它。
请注意,gcc
程序通常在内部使用临时文件(例如,用于生成的汇编程序文件或目标文件)。如果您将gcc
添加到-v
编译命令,例如,您就会看到它们。如果您使用gcc
汇编foo.c
。所以没有实际的理由避免使用C源文件(因为gcc -v foo.c -o fooprog
使用临时文件!)。
如果要在正在运行的程序中动态生成代码,可以生成临时C代码,然后将其编译为临时plugin(使用position-independent code)然后dynamically load该插件(例如在Linux上使用dlopen(3)&amp; dlsym(3));但您也可以使用JIT compiling或GCCJIT或LLVM等asmjit库等。当然,这需要您operating system的一些支持(例如增长virtual address space):在纯标准C11(阅读n1570)中,函数集在构建时固定,因为在translation units的联合中定义了1}}包含您的程序的gcc
个文件集,并且您无法在运行时生成代码。
如果你想在某些shell script中生成一些C程序,最好使用临时文件,例如使用.c
,tempfile
等...(并在mktemp
和EXIT
信号上使用trap
builtin以在脚本终止时删除临时文件。 / p>
如果您在build中生成了一些临时C代码,则可以配置好的build automation程序(例如GNU make
或ninja
)来删除这些临时C文件(例如阅读TERM
的{{3}}。
还要研究像Common Lisp这样的intermediate files编程语言。例如,homoiconic在每次SBCL交互时都会编译成机器代码。
答案 3 :(得分:0)
为什么不让脚本运行命令,而不是管道它:
gcc foo.c
同时仍然保持重定向到foo.c
echo '#include<stdio.h>
void main()
{
printf("Hello!");
}' > foo.c
gcc foo.c
如果您希望在gcc创建可执行文件之后通过在末尾添加
,则可以删除foo.c.rm foo.c