找到你要的答案

Q:Creating a dynamic array of char* from a char* text using strtok_s

Q:创建一个动态数组char *使用strtok_s文本字符串

My search here got many results, but none quite like so that I could find a solution to my problem.

I'm creating a Mathcad UserEFI DLL in C using Visual Studio 2013. I don't want to use strings, only char*.

Now, I want to emulate the console main function, which uses char* argv[] to access the parameters of a called executable. Mathcad will call the DLL with a string like "-T=3 z h 13". All I want is to parse this text into an array of char*, just like argv[] would be if I called an executable with this added parameters. I hope I expressed this in an understandable way. I use strtok_s to parse the text and one has to consider, that every token can have a different size.

The error must lie in the following function:

typedef struct tArgReturnType  {
    int ACount;
    char** Argus;
} ARGRETURN;

ARGRETURN ParseStringToArgs(char* text) {
    char *token = NULL;
    char *nextToken = NULL;
    int argCount = 0;
    char* temptext = NULL;
    strcpy(temptext, text);

    char** uebergabe = (char**)malloc(sizeof(char**)); 

    token = strtok_s(temptext, " ", &nextToken); 

    while (token != NULL) {
        argCount++;
        uebergabe = (char**)realloc(uebergabe, sizeof(uebergabe)+sizeof(token));
        uebergabe[argCount - 1] = token;
        token = strtok_s(NULL, " ", &nextToken);
    }
    ARGRETURN ReturnVar;
    ReturnVar.ACount = argCount;
    ReturnVar.Argus = (char**)malloc(sizeof(uebergabe));
    memcpy(ReturnVar.Argus, uebergabe, sizeof(uebergabe));
    free(uebergabe);

    return ReturnVar;
}

I'm sure that this is a complete mishmash of heap memory allocation failures (as indicated by the error the mathcad compiler gives me), since I modified this code multiple times while trying to find a solution. I'm just utterly confused now.


Updated Code:
typedef struct tArgReturnType  {
    int ACount;
    char** Argus;
} ARGRETURN;

ARGRETURN ParseStringToArgs(char* text) {
    char *token = NULL;
    char *nextToken = NULL;
    int argCount = 0;
    char* temptext = malloc(strlen(text) + 1);
    strcpy(temptext, text);

    char** uebergabe = malloc(sizeof(char**)); 

    token = strtok_s(temptext, " ", &nextToken); 

    while (token != NULL) {
        argCount++;
        uebergabe = (char**)realloc(uebergabe, sizeof(uebergabe)+sizeof(token));
        uebergabe[argCount - 1] = token;
        token = strtok_s(NULL, " ", &nextToken);
    }
    ARGRETURN ReturnVar;
    ReturnVar.ACount = argCount;
    ReturnVar.Argus = malloc(sizeof(uebergabe));
    memcpy(ReturnVar.Argus, uebergabe, sizeof(uebergabe));
    free(uebergabe);
    free(temptext);

    return ReturnVar;
}

我在这里的搜索有很多结果,但没有一个非常像我能找到一个解决我的问题。

我在C使用Visual Studio 2013创建Mathcad userefi DLL。我不想使用字符串,只有字符*。

Now, I want to emulate the console main function, which uses char* argv[] to access the parameters of a called executable. Mathcad will call the DLL with a string like "-T=3 z h 13". All I want is to parse this text into an array of char*, just like argv[] would be if I called an executable with this added parameters. I hope I expressed this in an understandable way. I use strtok_s to parse the text and one has to consider, that every token can have a different size.

错误必须位于以下功能:

typedef struct tArgReturnType  {
    int ACount;
    char** Argus;
} ARGRETURN;

ARGRETURN ParseStringToArgs(char* text) {
    char *token = NULL;
    char *nextToken = NULL;
    int argCount = 0;
    char* temptext = NULL;
    strcpy(temptext, text);

    char** uebergabe = (char**)malloc(sizeof(char**)); 

    token = strtok_s(temptext, " ", &nextToken); 

    while (token != NULL) {
        argCount++;
        uebergabe = (char**)realloc(uebergabe, sizeof(uebergabe)+sizeof(token));
        uebergabe[argCount - 1] = token;
        token = strtok_s(NULL, " ", &nextToken);
    }
    ARGRETURN ReturnVar;
    ReturnVar.ACount = argCount;
    ReturnVar.Argus = (char**)malloc(sizeof(uebergabe));
    memcpy(ReturnVar.Argus, uebergabe, sizeof(uebergabe));
    free(uebergabe);

    return ReturnVar;
}

I'm sure that this is a complete mishmash of heap memory allocation failures (as indicated by the error the mathcad compiler gives me), since I modified this code multiple times while trying to find a solution. I'm just utterly confused now.


Updated Code:
typedef struct tArgReturnType  {
    int ACount;
    char** Argus;
} ARGRETURN;

ARGRETURN ParseStringToArgs(char* text) {
    char *token = NULL;
    char *nextToken = NULL;
    int argCount = 0;
    char* temptext = malloc(strlen(text) + 1);
    strcpy(temptext, text);

    char** uebergabe = malloc(sizeof(char**)); 

    token = strtok_s(temptext, " ", &nextToken); 

    while (token != NULL) {
        argCount++;
        uebergabe = (char**)realloc(uebergabe, sizeof(uebergabe)+sizeof(token));
        uebergabe[argCount - 1] = token;
        token = strtok_s(NULL, " ", &nextToken);
    }
    ARGRETURN ReturnVar;
    ReturnVar.ACount = argCount;
    ReturnVar.Argus = malloc(sizeof(uebergabe));
    memcpy(ReturnVar.Argus, uebergabe, sizeof(uebergabe));
    free(uebergabe);
    free(temptext);

    return ReturnVar;
}
answer1: 回答1:
ARGRETURN ParseStringToArgs(const char* text) {
  ARGRETURN ReturnVar = { 0 };
  int n = 0;
  char temp[100];

  while (sscanf(text += n, "%99s%n", temp, &n) == 1) {
    ReturnVar.Argus = realloc(ReturnVar.Argus, ++ReturnVar.ACount*sizeof(*ReturnVar.Argus));
    strcpy(ReturnVar.Argus[ReturnVar.ACount - 1] = malloc(strlen(temp) + 1), temp);
  }

  return ReturnVar;
}
  • 'sizeof(text)' is a great mistake
  • don't use ugly strtok(_s), it's not reentrant, destroys the string, ...
  • use sscanf instead
ARGRETURN ParseStringToArgs(const char* text) {
  ARGRETURN ReturnVar = { 0 };
  int n = 0;
  char temp[100];

  while (sscanf(text += n, "%99s%n", temp, &n) == 1) {
    ReturnVar.Argus = realloc(ReturnVar.Argus, ++ReturnVar.ACount*sizeof(*ReturnVar.Argus));
    strcpy(ReturnVar.Argus[ReturnVar.ACount - 1] = malloc(strlen(temp) + 1), temp);
  }

  return ReturnVar;
}
  • 'sizeof(text)' is a great mistake
  • don't use ugly strtok(_s), it's not reentrant, destroys the string, ...
  • use sscanf instead
c  arrays  parsing  memory  char