我正在使用 Matlab Coder 将一些 Matlab 代码转换为 C++,但是我在将整数转换为字符串时遇到了问题。
int2str()
不支持代码生成,因此我必须找到其他方法将整数转换为字符串。我已经尝试过谷歌搜索,但没有成功。这真的可能吗?
我正在使用 Matlab Coder 将一些 Matlab 代码转换为 C++,但是我在将整数转换为字符串时遇到了问题。
int2str()
不支持代码生成,因此我必须找到其他方法将整数转换为字符串。我已经尝试过谷歌搜索,但没有成功。这真的可能吗?
function s = thePainfulInt2Str( n )
s = '';
is_pos = n > 0; % //save sign
n = abs(n); %// work with positive
while n > 0
c = mod( n, 10 ); % get current character
s = [uint8(c+'0'),s]; %// add the character
n = ( n - c ) / 10; %// "chop" it off and continue
end
if ~is_pos
s = ['-',s]; %// add the sign
end
while
条件改为 n>0
。 - Luis Mendointmin
,这会打印出一个不正确的字符串,因为abs(n)
会饱和。例如,abs(intmin('int32'))
将饱和,以便打印-intmax('int32')
。可以添加一个检查来检查intmin
,然后将s(end)
加一。 - Ryan Livingstonsprintfc
这个未记录的函数怎么样?你能检查一下吗? - Robert Seifertsprintfc
不起作用了。一开始它没有警告,原因不明,但现在它有了。所以我想你必须手动处理。@thewaywewalk - ein123sprintf
通用功能的解决方法:function s = sprintf(f, varargin)
if (coder.target('MATLAB'))
s = builtin('sprintf',f,varargin{:});
elseif (coder.target('MEX'))
s = builtin('sprintf',f,varargin{:});
else
coder.cinclude('stdio.h');
s = char(zeros(1024,1));
cf = [f,0]; % NULL-terminated string for use in C
coder.ceval('sprintf_s', coder.ref(s(1)), int32(1024), coder.rref(cf(1)), varargin{:});
end
2)确保不通过coder.extrinsic
指定sprintf
为外部函数。
3)在生成代码时,如果您使用codegen
函数,则需要将新创建的“sprintf.m”所在的文件夹指定为附加包含目录。这可以通过-I
开关完成。如果您使用Coder App,则可以在“更多设置 -> 自定义代码 -> 附加包含目录”下的“生成”选项卡中完成。
4)将整数转换为字符串,方法如下:s=sprintf('%d',int32(n));
注:
sprintf
函数,并且每次从生成的代码中调用sprintf
时都会执行该文件。通过将此文件放置在Matlab路径之外的文件夹中,可以避免从其他代码中调用它。调用coder.target
还有助于在正常的Matlab会话或MEX文件中导航回内置函数。sprintf_s
指示C++编译器在结果超过此值时抛出运行时异常。这可以防止仅在较晚时才发现的内存损坏,并且更难追溯到有问题的调用。此限制可以根据您自己的要求进行修改。sprintf
之前,必须将其强制转换为正确的类别,例如将其转换为int32
以匹配格式字符串中的%d
。在使用Matlab Coder时,使用fprintf
也需要遵守此要求。但是,在fprintf
情况下,Matlab Coder会为您捕获类型错误。对于sprintf
,C++编译器可能会失败,或者生成的字符串可能包含错误。f
已NULL结尾,但其他字符串参数的NULL结尾仍然是调用函数的责任。cf = [f, 0]; coder.ceval(...,coder.rref(cf(1)));
。由MATLAB Coder生成的字符数组没有空终止符。如果不这样做,将导致生成的代码出现未定义的行为。 - Ryan Livingston编辑:从MATLAB R2018a开始,sprintf
支持由MATLAB Coder生成的代码。
截至R2018a的答案
您还可以使用coder.ceval
调用C运行时的sprintf
或snprintf
。这样做的好处是,它使得支持浮点输入变得非常容易。您也可以通过调整格式字符串来更改所需的格式。
假设您的编译器提供snprintf
,则可以使用以下命令:
function s = cint2str(x)
%#codegen
if coder.target('MATLAB')
s = int2str(x);
else
coder.cinclude('<stdio.h>');
assert(isfloat(x) || isinteger(x), 'x must be a float or an integer');
assert(x == floor(x) && isfinite(x), 'x must be a finite integer value');
if isinteger(x)
switch class(x)
% Set up for Win64, change to match your target
case {'int8','int16','int32'}
fmt = '%d';
case 'int64'
fmt = '%lld';
case {'uint8','uint16','uint32'}
fmt = '%u';
otherwise
fmt = '%llu';
end
else
fmt = '%.0f';
end
% NULL-terminate for C
cfmt = [fmt, 0];
% Set up external C types
nt = coder.opaque('int','0');
szt = coder.opaque('size_t','0');
NULL = coder.opaque('char*','NULL');
% Query length
nt = coder.ceval('snprintf',NULL,szt,coder.rref(cfmt),x);
n = cast(nt,'int32');
ns = n+1; % +1 for trailing null
% Allocate and format
s = coder.nullcopy(blanks(ns));
nt = coder.ceval('snprintf',coder.ref(s),cast(ns,'like',szt),coder.rref(cfmt),x);
assert(cast(nt,'int32') == n, 'Failed to format string');
end
long long
可用并将64位整数映射到它上面。
num2str
被支持吗?这是这种类型中最通用的函数。 - buzjwa