简体   繁体   English

C结构编译错误

[英]C Struct Compile Error

Why does the following code produce a compile-time error? 为什么以下代码会产生编译时错误? I cannot seem to see why the types are mismatched. 我似乎看不出为什么类型不匹配。

typedef char f_string[MAX_CHARS+1] ;    /* string for each field */

/*
 * A parsed CSV line, with the number of fields and upto MAX_FIELDS themselves.
*/

typedef struct {
    int nfields ;               /* 0 => end of file */
    f_string field[MAX_FIELDS] ;        /* array of strings for fields */
} csv_line;

....

csv_line sut;
sut.field[0] = "Name, "; //Compile-time error.

Error being: 错误是:

error: incompatible types in assignment

You are trying to assign a const char * to a char[] , which is not quite the same thing. 您试图将const char *分配给char[] ,这不是完全一样的事情。 This would work if your f_string were defined as 如果将f_string定义为

typedef const char * f_string;

What you are looking for here is 您在这里寻找的是

strcpy ( sut.field[0], "Name, " );

Or use strncpy so that you can specify the size of the destination buffer .. 或使用strncpy以便您可以指定目标缓冲区的大小。

strncpy ( sut.field[0], "Name, ", MAX_CHARS )

That will keep you from overrunning your buffer. 这样可以防止您溢出缓冲区。

You'll need to use something like: 您将需要使用类似:

strcpy( sut.field[0],"Name, ");

You can't assign strings like you tried other except as an initializater at declaration time. 您不能像尝试其他字符串那样分配字符串,只能在声明时将其初始化。

the type of sut.field[0] is array-of-char of size MAX_CHARS+1 - you cannot assign a string pointer to an array of characters. sut.field [0]的类型是大小为MAX_CHARS + 1的字符数组-您不能将字符串指针分配给字符数组。

You'd either need to change the type of csv_line::field to a const char*, or just do a string copy of the literal "Name, " to the target array. 您要么需要将csv_line :: field的类型更改为const char *,要么只需将文字“名称”的字符串副本复制到目标数组即可。

Note that both strcpy() and strncpy() alone are unsafe: the first might overflow your buffer, and the second might leave it without a NUL terminator. 请注意,单独使用strcpy()strncpy()都是不安全的:第一个可能会使您的缓冲区溢出,第二个可能使它没有NUL终止符。 You must be aware of BOTH of these circumstances even if you "know" that your string in question won't ever overflow. 即使您“知道”有问题的字符串永远不会溢出,您也必须同时意识到这两种情况。

Use a helper function to do this safely: 使用辅助函数可以安全地执行此操作:

char * strncopy(char *dst, const char *src, int dstsize)
{
    strncpy(dst, src, dstsize-1);
    dst[dstsize-1] = '\0';

    return dst;
}

Then: 然后:

strncopy(sut.field[0], "Name, ", sizeof sut.field[0]);

sut.field[0] is a char[MAX_CHARS+1] sut.field[0]char[MAX_CHARS+1]

"Name, " is a const char* "Name, "是一个const char*

Try this: 尝试这个:

strcpy(sut.field[0], "Name, ");

The type of sut.field[0] is indeed char [MAX_CHARS+1] . sut.field[0]的类型确实是char [MAX_CHARS+1] However, most of the other answers have the type of "Name, " wrong - it is actually of type char [7] (use sizeof "Name, " for an easy demonstration of this). 但是,大多数其他答案的类型都是"Name, " ,这是错误的-实际上它的类型为char [7] (使用sizeof "Name, "以方便说明)。

Nonetheless, you still cannot directly assign a char [7] to a char [MAX_CHARS+1] . 尽管如此,您仍然不能直接将char [7]分配给char [MAX_CHARS+1] You cannot even directly assign a char [7] to another char [7] ( initialisation is treated differently from assignment in this way). 您甚至不能直接将一个char [7]分配给另一个char [7]初始化与这种分配的处理方式不同)。

The answer is probably just to use a coyping function - for example, if you are certain that MAX_CHARS >= 6 , then you can just use strcpy() . 答案可能只是使用coyping函数-例如,如果您确定MAX_CHARS >= 6 ,则可以只使用strcpy() If you cannot be sure about the length being correct, then you can use strncat() as as truncating string copy: 如果不确定长度是否正确,则可以将strncat()用作截断字符串副本:

sut.field[0][0] = '\0';
strncat(sut.field[0], "Name, ", MAX_CHARS);

(Note that despite the name, strncpy() is not suitable for this, and in fact is very rarely the desired function at all). (请注意,尽管有名称, strncpy() 适用于此功能,但实际上很少是所需的功能)。


It is worth pointing out, however, that you can indirectly assign arrays (of the same type) if they are wrapped up inside a struct . 值得指出的是,如果将数组包装在struct ,则可以间接分配(相同类型的)数组。 This means that the following will work (if you have a C99 compiler): 这意味着以下操作将有效(如果您具有C99编译器):

typedef struct { char s[MAX_CHARS+1] } f_string;    /* string for each field */

csv_line sut;
sut.field[0] = (f_string){"Name, "};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM