1

我想定义一个函数,它根据 val 是字符串还是数值返回字符串 "NaN" 或 sprintf("%g",val) 。最初我试图测试是否定义了 val (使用 gnuplot “exists”函数),但似乎我无法将任何未定义的变量传递给函数(在评估函数之前发出错误)。因此:有没有办法在函数内部测试参数是字符串还是数字?

我搜索了一个函数 isstring ,我可以以某种方式使用它

myfunc(val)=(isstring(val)?"NaN":sprintf("%g",val))

目标是在未定义变量的情况下输出变量值而不冒错误的风险。但是,如果我想要一个用于许多变量的紧凑代码,我需要它作为一个函数。

4

2 回答 2

2

Gnuplot 并不具备许多其他语言所具备的自省能力。事实上,它对待字符串和数字(​​至少是整数)非常相似:

print "1"+2  #prints 3
a=1
print "foo".a  #prints foo1

我不确定这是如何在内部实现的。但是,您要开始工作非常棘手。

实际上,我认为您的第一次尝试(检查变量是否存在)更明智,因为在 gnuplot 中进行类型检查是不可能的*。您可以将变量名称作为字符串传递给函数,但问题是您似乎没有该值的句柄。一切似乎都丢失了——但是等等,gnuplot 有一个eval语句,当给定一个字符串时,它会评估它。这看起来很棒!不幸的是,它是一个语句,而不是一个函数(所以它不能在函数中使用——argv!)。我能想到的最佳解决方案是编写一个函数,该函数返回一个可以使用eval. 开始:

def exists_func(result,var)=sprintf("%s=exists('%s')?sprintf('%g',var):'NaN'",result,var,var)

现在当你想使用它时,你只需在它前面加上eval

a=3
eval exists_func("my_true_result","a")
print my_true_result #3
eval exists_func("my_false_result","b")
print my_false_result #NaN

这有点不合时宜。在大多数编程语言中,您可能想要执行以下操作:

my_true_result=exists_func(a)

但是,唉,我不知道如何使该表格起作用。

当然,同样的事情总是与eval. 不要将此函数与不受信任的字符串一起使用。

*我实际上不知道这是不可能的,但我一直无法让它工作

编辑

针对您对上述问题的评论,我认为这样的功能会更直观一些:

def fmt(x)=(x==x)?sprintf("%g",x):"NaN"

使用这个函数,你的“sentinal/default”值应该是NaN而不是"undefined",但看起来这应该不会有太大的不同......(真的,如果你愿意而"nan"不是根本"NaN"不需要这个函数——sprintf就可以了。(请注意,这是有效的,因为根据 IEEE,NaN它不等于任何东西(甚至它本身))。

于 2012-07-27T13:15:23.497 回答
1

这些天你用 gnuplot 帮了我很多。我想回馈你一些东西,因为我找到了一个检查变量是否为数字的解决方案。这有助于确定可以在其上使用哪些运算符(例如 == 用于数字,eq 用于字符串)。

解决方案不是很简单,但它确实有效。它将 gnuplot 的打印命令重定向到一个临时文件,将变量写入文件并使用(<> 是伪代码)print myvar评估文件的第一行。system("perl -e '<isnumeric(line#1 in temp file)?>' ")让我知道是否有改进的空间,让我听听您的建议!

示例: myvar 是一个浮点数。任何整数(1 或“1”)或字符串值(“*”)也可以!

myvar = -2.555  
 # create temporary file for checking if variables are numeric  
Int_tmpfle = "tmp_isnumeric_check"  
 # redirect print output into temp file (existing file is overwritten)  
set print Int_tmpfle    
 # save variable's value to file  
print myvar             
 # check if file is numeric with Perl's 'looks_like_number' function   
isnumeric = system("perl -e 'use Scalar::Util qw(looks_like_number); \  
open(FLE,".Int_tmpfle."); $line = < FLE >; \  
if (looks_like_number($line) > 0) {print qq(y)} ' ")  
 # reset print output to < STDOUT> (terminal)  
set print "-"           
 # make sure to use "," when printing string and numeric values  
if (isnumeric eq "y") {print myvar," is numeric."} else {print myvar," is not numeric."}
于 2013-02-20T12:18:57.133 回答