我使用 Matlab Coder 将一些Matlab代码转换为C ++,但是我无法将整数转换为字符串。
代码生成不支持 int2str()
,因此我必须找到一些其他方法将int转换为字符串。我试过谷歌搜索,没有成功。这甚至可能吗?
答案 0 :(得分:8)
这可以手动完成(但非常痛苦)
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
答案 1 :(得分:6)
sprintf
是另一个非常基本的函数,所以它也可以在C ++中起作用:
#my-wrapper {
Width:700px;
}
#sidebar-wrapper {
width:200px;
display:none;
}
它也是x = int64(1948)
str = sprintf('%i',x)
使用的基础功能。
根据这个comprehensive list of supported functions,正如Matt在评论中指出的那样,int2str
不受支持,这是令人惊讶的。然而,有一个未记录的辅助函数(因此不在列表中)sprintfc
似乎有用,可以等效使用:
sprintf
答案 2 :(得分:1)
Edit: As of MATLAB R2018a, sprintf
is supported for code generation by MATLAB Coder.
Pre R2018a Answer
You could also call the C runtime sprintf
or snprintf
using coder.ceval
. This has the benefit of making supporting floating point inputs easy as well. You can also change the formatting as desired by tweaking the format string.
Supposing that your compiler provides snprintf
one could use:
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
Note that you'll possibly need to tweak the format string to match the hardware on which you're running since this assumes that long long
is available and maps 64-bit integers to it.
答案 3 :(得分:1)
I use the following workaround to enable sprintf
for general use with Matlab Coder:
1) Create the following m-file named "sprintf.m", preferably in a folder NOT on your Matlab path:
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) Ensure that sprintf
is not specified as extrinsic via coder.extrinsic
3) Specify the folder containing the newly created "sprintf.m" as additional include directory when generating code. If you use the codegen
function, this can be done via the -I
switch. If you use the Coder App, this can be done under "More Settings -> Custom Code -> Additional include directories" from the "Generate" tab.
4) Convert from int to string as follows: s=sprintf('%d',int32(n));
Notes:
sprintf
function and executes instead of the built-in function every time you call sprintf
from generated code. By placing this file in a folder that is not on the Matlab path, you avoid calling it from other code made to run in Matlab. The coder.target
call also helps to navigate back to the built-in function in case this gets called in a normal Matlab session or from a MEX file.sprintf_s
instructs the C++ compiler to throw a runtime exception if the result exceeds this value. This prevents memory corruption that is often only caught much later and is harder to trace back to the offending call. This limit can be modified to your own requirements.sprintf
, e.g. cast to int32
to match a %d
in the format string. This requirement is the same when using fprintf
with Matlab Coder. However, in the fprintf
case, Matlab Coder catches type errors for you. For sprintf
, the C++ compiler may fail or the resulting string may contain errors.f
is NULL-terminated, but NULL-termination of other string arguments remains the responsibility of the calling function.