简体   繁体   English

将字符串数组转换为字符串数组

[英]Convert an array of string into an array array of strings

I have an array of strings: {"foo", "bar", "baz"} and I want to convert it into an array array of string: {{"foo", "bar", "baz"}}, (part of a bigger project).我有一个字符串数组:{“foo”、“bar”、“baz”},我想将它转换为字符串数组:{{“foo”、“bar”、“baz”}},(更大项目的一部分)。 My program will use args as an array of strings, so the input is: ./a.out foo bar baz.我的程序将使用 args 作为字符串数组,因此输入为:./a.out foo bar baz。 With 1 and 3 arguments it works nice, but with 2 arguments it gives me segmentation fault.使用 1 和 3 arguments 效果很好,但是使用 2 arguments 它给了我分段错误。 My code:我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char ***args2cmd(int argc, char **args){ 
  //Create array of array of strings
  char ***arr = malloc(sizeof(char ***));
  int tami = 0;
  int tamj = 0;
  //Arry of strings
  arr[tami] = malloc(sizeof(char **));
  //String
  arr[tami][tamj] = malloc(sizeof(char *));

  for(int i=0; i<argc; i++){  
    tamj++;
    arr = realloc(arr, tamj * sizeof(**arr));
    arr[tami][tamj-1] = args[i]; 
  }
  return arr;
}

int main(int argc, char **args) {
  char ***arr = args2cmd(argc, args);
  for(int i=0; arr[i]; i++){
    for(int j=0; arr[i][j]; j++){
      printf("%s ", arr[i][j]);
    }
    printf("\n");
  }

  return 0; 
}

Bellow is a little code demonstration of how you could use an array of void pointers to accomplish your task. Bellow 是一个小代码演示,展示了如何使用void指针数组来完成任务。 Code is fully commented with all relevant explanations.代码用所有相关解释进行了全面注释。 Compile with gcc -o astr astr.c .使用gcc -o astr astr.c编译。

Call with ./astr hello world from command line , for example.例如./astr hello world from command line调用。

/* astr.c
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

/* @n is the number of string you passed the function */
char **build_array(int n, ...)
{
    /* no error checking...
     * +1 because we terminate the array with a NULL
     */
    char **s = malloc((n + 1) * sizeof(*s));
    va_list ap;
    int i;

    va_start(ap, n);
    for(i = 0; i < n; i++) 
        s[i] = va_arg(ap, char *);
    va_end(ap);

    /* terminate the array with a NULL */
    s[i] = NULL;
    return s;
}

int main(int argc, char **argv)
{
    /* array of strings is just an array of pointers...
     *
     * Since you can play around with void points _by the standard_,
     * we can just make an array of voids to hold whatever pointers we
     * want, IFF we keep track of the types for the conversions.
     *
     * Say we do:
     *
     *  astr[0] = argv; // this is type (char **)
     *
     *  and them we do
     *
     *  float **foo = astr[0]; // VALID SYNTAX, but WRONG SEMANTIC
     *  
     *  The above is valid syntax since we can convert to and from
     *  void pointers, but we stored (char**) in astr[0], not
     *  (float**), and this will blow up in your face.
     */
    void **astr;

    /* alloc space for the array of strings.
     * no error cheking!
     */
    astr = malloc(3 * sizeof(*astr));

    /* the first element is the command line.
     * You could make a function to copy @argv into a new array
     */
    astr[0] = argv;

    /* just a helper function to build some more arrays */
    for(int i = 1; i < 3; i++)
        astr[i] = build_array(3, "hello", "world", "!!!");

    for(int i = 0; i < 3; i++) {
        char **s = astr[i];
        printf("Array #%d at addr %p\n", i, s);

        /* This assumption is dangerous! You should always KNOW 
         * the size of your arrays
         */
        for(int j = 0; s[j]; j++) 
            printf("s[%d] = %s\n", j, s[j]);
    }

    return 0;
}

After your comment:在您发表评论后:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char ***args2cmd(int argc, char **args)
{
    //Create array of array of strings
    // FIRST malloc()
    char ***arr = malloc(sizeof(char ***));

    int tami = 0;
    int tamj = 0;

    /* arr => 1 slot for 1 array
     */

    //Arry of strings
    // SECOND malloc
    arr[tami] = malloc((argc + 1) * sizeof(char **));

    /* arr[tami] = malloc(sizeof(char**)) gives us just 
     * arr[0] => 1 slot, which doesn't make sense.
     *
     * So we change it, because WE KNOW the size of the array! It's 
     * going to hold argc + 1 strings. Why the +1? Because you use the
     * trick of stoping loops based on a NULL element.
     *
     *
     * Keep in mind that @tami is bound the the amount of space pointed
     * to by arr! So, that's the first malloc() you did.
     *
     */
    //String
    //arr[tami][tamj] = malloc(sizeof(char *));
    /* arr[0][0] = 1 slot
     *
     * If this is a string, why only one slot?
     * You need more space for strings, ie:
     *  arr[tami][tamj] = malloc(strlen(something))
     *
     * So we comment this out, since it doesn't make any sense here.
     */

    int i; /* so we can use it later for the NULL */
    for (i = 0; i < argc; i++) {
        /* strdup() will alloc space and copy the string you give it
         * to this new region, then it will return your region. It's
         * similar to doing:
         *  char *s1 = "hello":
         *  char *s2 = malloc(strlen(s1));
         *  return strcpy(s2, s1);
         */
        arr[tami][i] = strdup(args[i]);
    }
    /* you assume the arrays end with NULL, so you
     * have to put it here
     */
    arr[tami][i] = NULL;
    return arr;
}

int main(int argc, char **args)
{
    char ***arr = args2cmd(argc, args);
    for (int i = 0; arr[i]; i++) {
        for (int j = 0; arr[i][j]; j++) {
            printf("%s ", arr[i][j]);
        }
        printf("\n");
    }

    return 0;
}

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

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