我想将一个字符串存储到结构内的char数组中,当我访问char数组时,我希望结果与全局变量errCode中的值一起显示。当我访问结构的errDesc成员时,我希望结果为“错误检测到错误代码0xA0B0C0D0”,但由于使用strcpy复制字符串,因此我得到一个结果“错误代码%08lx检测到错误”。这是一个复制我的问题的示例代码:
int errCode = 0xA0B0C0D0;
void function(errpacket* ptr, int a, char* errString, ...);
typedef struct{
int err;
char errDesc;
}errpacket;
int main(){
errpacket* a;
void function(a, 10, "Error detected with error code %08lx", errCode);
return 0;
}
void function(errpacket* ptr, int a, char* errString, ...){
ptr->err = a;
strcpy(&ptr->errDesc, errString);
}
如果我的实施不正确,请建议我做一些我想做的事情。另请指出上述代码中的错误。
答案 0 :(得分:1)
在声明typedef
errpacket
结构function(...)
函数a
中的变量main()
只是一个指针。如果您尝试写入未初始化的指针,则会在函数内部出现分段错误。
成员errDesc
只能保存一个字符,而不是字符串或字符数组。
试试这个......
int errCode = 0xA0B0C0D0;
typedef struct {
int err;
char* errDesc;
} errpacket;
void function (errpacket* ptr, int a, char* errString, ...);
int main () {
errpacket a;
function(&a, 10, "Error detected with error code %08lx", errCode);
return 0;
}
void function (errpacket* ptr, int a, char* errString, ...) {
ptr->err = a;
ptr->errDesc = strdup( errString);
}
答案 1 :(得分:0)
您不能使用单个char
变量来保存整个字符串。
可以做的是将errDesc
声明为固定长度的数组(如果知道错误描述可以包含的最大字符数),或指针使用malloc
动态分配,然后使用free
释放。
数组案例:
#define MAX_ERR_STRING_SIZE 500
typedef struct
{
int err;
char errDesc[MAX_ERR_STRING_SIZE];
} errpacket;
// You can now use strcpy() to copy to errpacket::errDesc assuming none of the error strings exceed MAX_ERR_STRING_SIZE
动态记忆:
typedef struct
{
int err;
char *errDesc;
} errpacket;
// Take note of the new parameter: int errStringLength,
void function(errpacket* ptr, int a, char* errString, int errStringLength, ...){
ptr->err = a;
ptr->errDesc = malloc((errStringLength + 1) * sizeof(char));
if(ptr->errDesc == NULL)
{
perror("malloc");
exit(EXIT_FAILURE);
}
strcpy(&ptr->errDesc, errString);
}
使用完ptr
后,您需要致电free(ptr->errDesc);
取消分配字符串。
答案 2 :(得分:0)
尝试此修复:
#include <stdarg.h> //to be added for vsprintf use
int errCode = 0xA0B0C0D0;
void function(errpacket* ptr, int a, char* errString, ...);
typedef struct{
int err;
char *errDesc;
}errpacket;
int main(){
errpacket a; //you need allocate memory if you use a pointer here
void function(&a, 10, "Error detected with error code %08lx", errCode);
return 0;
}
void function(errpacket* ptr, int a, char* errString, ...){
ptr->err = a;
ptr->errDesc = malloc(strlen(errString)+1);
memset(ptr->errDesc, 0, strlen(errString)+1);
/*if(ptr->errDesc != NULL)
{
strcpy(ptr->errDesc, errString);
}*/
// use like following if you want use a formatted string
if(ptr->errDesc != NULL)
{
va_list args;
va_start (args, errString);
vsprintf (ptr->errDesc, errString, args);
va_end (args);
}
}
答案 3 :(得分:0)
我认为你真的不想要一个带有变量参数的函数,比如printf。下面的解决方案只是期望你最终使用的参数。请注意,我不使用用户提供的格式字符串;这被认为是一种安全风险。我还使用snprintf
(而不是简单的sprintf
)来防止错误消息长于结构中的数组大小。数组大小是一个定义,因此可以轻松更改。
具体修正:
%s
格式说明符的字符串。
#include<stdio.h>
int errCode = 0xA0B0C0D0;
#define MAX_ERRDESC_LEN 80 // avoid literals
typedef struct{
int err;
char errDesc[MAX_ERRDESC_LEN]; // provide actual space for the message
}errpacket;
void printErrPack(FILE *f, errpacket *ep){
fprintf(f, "Error packet:\n");
fprintf(f, " err = 0x%x:\n", ep->err);
fprintf(f, " desc = ->%s<-\n", ep->errDesc);
}
// Standard function with fixed argument count and types
void function(errpacket* ptr, int errNo, char* errString, int errCodeArg){
ptr->err = errNo;
// snprintf "prints" into a string
snprintf( ptr->errDesc, // print destination
MAX_ERRDESC_LEN, // max length, no buffer overflow
"%s with error code %x", // do not use user string as format
errString, // user supplied string, printed via %s
errCodeArg );
}
int main(){
errpacket a; // define an actual object, not a pointer
// pass the address of the object a
function(&a, 0xdead, "Error detected ", errCode);
printErrPack(stdout, &a);
return 0;
}