strcpy()和char

问题描述 投票:-1回答:4

我想将一个字符串存储到结构内的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);
}

如果我的实施不正确,请建议我做一些我想做的事情。另请指出上述代码中的错误。

c string struct
4个回答
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);
   }
}

1
投票
  1. 在宣布typedef之前,你必须errpacket结构function(...)
  2. 函数a中的变量main()只是一个指针。如果您尝试写入未初始化的指针,则会在函数内部出现分段错误。

成员errDesc将只保存一个char,而不是字符串或char数组。

试试这个...

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);
}

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);来取消分配字符串。


0
投票

我不认为你真的想要一个带有变量参数的函数,比如printf。下面的解决方案只是期望你最终使用的参数。请注意,我不使用用户提供的格式字符串;这被认为是一种安全风险。我还使用了snprintf(而不是简单的sprintf)来防止错误消息,这些错误消息比结构中的数组大小更长。数组大小是一个定义,因此可以轻松更改。

具体修复:

  • 正确的声明顺序(在使用之前定义结构类型)
  • 定义一个实际的错误包对象(而不仅仅是一个未初始化的指针)
  • 在消息的错误包中提供实际内存
  • 为错误包提供打印功能
  • 不要让用户代码指定printf格式; print用户提供的字符串,长度受保护的%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;
}
© www.soinside.com 2019 - 2024. All rights reserved.