在调用函数时,我遇到了麻烦,它将指向字符串的指针作为参数。我需要获得一个Element的名字。
// method
void getStringFromCsv( char ** str );
让我介绍一下我正在使用的结构(不是由我编写的,而是一个更大的项目的一部分,我无法修改它们)。
// typedefs
typedef char T_CHAR64[64];
typedef T_CHAR64 T_SYMBOL;
// generic element
typedef struct Element
{
T_SYMBOL name;
} T_Element;
// csv element
typedef struct CsvElement
{
Element * pElement;
int id;
} T_csvElement;
所以,基本上,我以为我会这样调用这个函数:
T_Element * pData; // Not null, filled earlier
getStringFromCsv( &pData->pElement->name );
但这不起作用(警告:从不兼容的指针类型传递'STR_toCsv'的参数1)。我在NetBeans 6.8中使用gcc。
我做了很多事......
T_SYMBOL foo = "foo";
T_SYMBOL * pFoo = &foo;
getStringFromCsv( pDef->name, &pFoo ); // error : passing from incompatible pointer type
T_CHAR * pBar = &foo; // error : init from incompatible pointer type
T_CHAR * pBaz = &(foo[0]); // OK
getStringFromCsv( pDef->name, &pBaz ); // OK
T_SYMBOL * pFooTest = &(foo[0]); // error : init from incompatible pointer type
...但最终将名字命名为char **:
getStringFromCsv( (char**) &pData->pElement->name );
我的代码出了什么问题? 基本上,SYMBOL = CHAR *,对吧?为什么SYMBOL *!= CHAR **? 我很确定我错过了一些简单的东西但是现在......什么都没有来。
修改 这是getStringFromCsv:
void getStringFromCsv( char ** data )
{
// pDesc is defined and not null
csvDescriptorCat( pDesc, *data);
csvDescriptorCat( pDesc, "\t");
}
void csvDescriptorCat( CsvDescriptor * pDesc, char* str)
{
int len;
if( str != NULL)
{
len = strlen(str);
strcpy( &pDesc->line[pDesc->pos], str);
pDesc->pos += len;
}
}
答案 0 :(得分:2)
name
是一个字符数组,所以& name给你一个指向char [64]的指针,因为Vicky已经回答了。但是渲染使事情变得更糟,因为它告诉编译器将数组的第一个字符视为指向真实数组的指针。
请参阅C-FAQ:http://c-faq.com/aryptr/aryptr2.html
我认为你可以在这里使用临时char *:
char *tmp = pData->pElement->name; // array decays to pointer
getStringFromCsv(&tmp);
如果函数需要这个。期待char**
,确保它不会尝试重新分配内存。只需填写char*
即可。
答案 1 :(得分:2)
如果您希望将&pData->pElement->name
传递给函数,则必须将该函数声明为:
void getStringFromCsv(T_SYMBOL * str);
或者你可以使用临时char *
作为安全提供 - 但这样做没有多大意义,因为无法使用char *
值的任何更新 - {{1无法修改成员,因为它是一个数组。
您也可以将该函数声明为:
->name
...并将其命名为:
void getStringFromCsv( char * str );
(在这种情况下,该函数仍然可以更改getStringFromCsv( pData->pElement->name );
数组的内容。你不能做的是改变数组本身的位置。)
除了Secure的选项之外,如果您的编译器支持C99复合文字,还有另一种方法:
->name
答案 2 :(得分:1)
#include <stdio.h>
int main(int argc, const char *argv[])
{
char x [5];
char *y;
printf("%08x\n", x);
printf("%08x\n", &x);
printf("%08x\n", y);
printf("%08x\n", &y);
return 0;
}
答案 3 :(得分:0)
考虑到这一点:http://c-faq.com/decl/strlitinit.html
char a[4] = "hello";
char* p = "hello";
不一样(即使它们似乎是)。 所以我的SYMBOL和CHAR *无法兑换,对吧?
是否有解决方法或其他解决方案?
答案 4 :(得分:-2)
是的,在封面T_SYMBOL处理就像char *。但是你已经将它声明为char [64],所以你传入一个指向char [64]的指针,而不是指向char的指针。编译器正在为您跟踪。
就这种情况而言,我会像你在问题结束时那样投出它。