6

假设我有一个S大小为 0x1 的结构,其中包含字段ab,向其中添加字段的最优雅方法是c什么?

通常我可以这样做:

S = struct('a',0,'b',0); %1x1 struct with fields a,b
S.c = 0

但是,如果我收到一个空结构,这将不再起作用:

S = struct('a',0,'b',0);
S(1) = []; % 0x1 struct with fields a,b
S.c = 0;
% A dot name structure assignment is illegal when the structure is empty.  
% Use a subscript on the structure.

我想了两种方法来解决这个问题,但两者都很丑陋,感觉像是变通方法而不是解决方案。(请注意,也应正确处理非空结构的可能性)。

  1. 向结构添加内容以确保其不为空,添加字段,并使结构再次为空
  2. 使用所需的字段名初始化新结构,用原始结构中的数据填充它,并覆盖原始结构

我意识到我关心空结构可能很奇怪,但不幸的是,如果字段名不存在,那么不由我管理的部分代码将会崩溃。我已经查看了help structhelp subsasgn并且还搜索了给定的错误消息,但到目前为止我还没有找到任何提示。因此非常感谢您的帮助!

4

4 回答 4

7

你可以使用deal来解决这个问题:

S = struct('a',0,'b',0);
S(1) = [];

[S(:).c] = deal(0);

这导致

S = 

1x0 struct array with fields:
    a
    b
    c 

这也适用于非空结构:

S = struct('a',0,'b',0);

[S(:).c] = deal(0);

这导致

S = 

    a: 0
    b: 0
    c: 0
于 2013-02-12T14:47:48.270 回答
2

怎么样

S = struct('a', {}, 'b', {}, 'c', {} );

创建一个空结构?

另一种方法是使用mexfile withmxAddField作为您遇到的错误的解决方法:

当结构为空时,点名结构分配是非法的。
在结构上使用下标。

于 2013-02-12T10:33:21.490 回答
2

你可以用它setfield来解决问题。

S = struct('a', {}, 'b', {});
S = setfield(S, {}, 'c', [])

这导致

S = 

0x0 struct array with fields:
    a
    b
    c
于 2015-06-27T08:03:20.177 回答
1

只是为了扩展@Shai 的答案,这里有一个简单的 MEX 函数,您可以使用:

addfield.c

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    char *fieldname;

    /* Check for proper number of input and output arguments */
    if (nrhs != 2) {
        mexErrMsgIdAndTxt("struct:nrhs", "Two inputs required.");
    } else if (nlhs > 1) {
        mexErrMsgIdAndTxt("struct:nlhs", "Too many output arguments.");
    } else if (!mxIsStruct(prhs[0])) {
        mexErrMsgIdAndTxt("struct:wrongType", "First input must be a structure.");
    } else if (!mxIsChar(prhs[1]) || mxGetM(prhs[1])!=1) {
        mexErrMsgIdAndTxt("struct:wrongType", "Second input must be a string.");
    }

    /* copy structure for output */
    plhs[0] = mxDuplicateArray(prhs[0]);

    /* add field to structure */
    fieldname = mxArrayToString(prhs[1]);
    mxAddField(plhs[0], fieldname);
    mxFree(fieldname);
}

例子:

>> S = struct('a',{});
>> S = addfield(S, 'b')
S = 
0x0 struct array with fields:
    a
    b
于 2013-05-02T18:06:37.780 回答