【问题标题】:combine the whole elements in the array and store it in index 0组合数组中的所有元素并将其存储在索引 0 中
【发布时间】:2014-11-07 10:56:12
【问题描述】:

我有一个值数组:

array1[] = {1, 32, 4, 12};

我想将其存储为每个值的十六进制表示形式的字符串(格式为"%02x"):

string = "0120040c";

我可以使用for 循环打印字符串就好了:

for (int i=0;i<array_size;++i)
    printf("%02x", array[i]);

但无法将结果字符串分配给 char 数组。我该怎么做?

【问题讨论】:

  • C 从 0 开始,更改为 array1[0] = 'a'(注意 ' 而不是 "),array2[1] = "apple" 应该是 array2[6] = "apple"array2[] = "apple"
  • 你的两个选择是非常不同的东西。同时向我们展示array1arary2是如何声明的。
  • 不清楚你想要什么。
  • 有无数非常好的教程/常见问题解答/...关于 C 字符串的工作原理。请先阅读这些内容。
  • @JasperKanbier:我已经编辑了您的问题,以反映您实际想要什么,因为您在 cmets 中所说的与您最初的问题导致所有人的想法相差甚远相信(因此投下反对票、近距离投票和 cmets 的弹幕)

标签: c arrays string char


【解决方案1】:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *join(int n, char *a[n]){
    int i;
    size_t lens[n], len=1;
    for(i=0;i<n;++i)
        len += (lens[i] = strlen(a[i]));
    char *cat = malloc(len);
    char *p = cat;
    for(i=0;i<n;++i){
        memcpy(p, a[i], lens[i]+1);
        p += lens[i];
    }
    return cat;
}

int main(void){
    char *array1[] = {"a", "p", "p", "l", "e"};
    char *string;
    int n = sizeof(array1)/sizeof(*array1);
    string = join(n, array1);
    puts(string);
    free(string);
    return 0;
}

【讨论】:

    【解决方案2】:

    显然您想创建一个字符串,将数组中的值显示为十六进制。这可以通过循环遍历字符串相对容易地完成,并使用一些snprintf 魔法。但首先,让我们确定我们需要知道什么,以及如何获取这些信息:

    • 为什么数组是大小
    • 我们的目标字符串中每个值将占用多少个字符
    • 我们如何访问数组,作为数组或指针(即:它是否传递给函数)

    如果您有支持 C99 或 C11 的编译器,则可以使用 VLA。首先,假设您有一个数组(而不是指针):

    const char * format = "%02x";//each value will be 2 chars + terminating 0
    int array[] = { 123, 32, 4354, 544};
    size_t arr_len = sizeof array/ sizeof *array;//get the nr of elements in the array
    char string[arr_len*2 + 1];//nr of array elements *2 (chars) + terminating 0
    for (int i=0;i<arr_len;++i)
    {//this is where the magic happens:
        snprintf(string + (i*2), 3, format, array[i]);
    }
    printf("The full hex string is: %s\n", string);
    

    现在让我们看看这个位:snprintf(string + (i*2), 3, format, array[i]);

    我正在使用string 数组,就好像它是一个指针,就好像string 包含一个指向string[0] 的内存地址。通过将i*2 添加到其中,我告诉snprintf 目标内存应该写入输出的位置从数组的第N 个元素开始。在第一次迭代中,i 为 0,因此 string + 0*2 == string + 0 == string,第二次为 string + (1*2) == string + 2 == &amp;string[2]。有效地连接输出。

    然后,我将 3 传递给 snprintf,告诉函数输出的最大长度为 3 个字符(包括终止 \0 字符)。这非常适合来自我们格式 "%02x" 的 2 个十六进制字符 + \0。然后通过array[i] 将十六进制值添加到字符串的末尾就很简单了。


    太好了,现在如果 array 被传递给一个函数,和/或你没有 VLA 怎么办?和上面一样,有一些不同。您必须计算数组的长度并将其传递给函数(计算方法如上所示)。您还必须自己为字符串分配内存(并释放它),这也不应该太难:

    char * get_hex_string(int *arr, size_t arr_len)
    {
        char * string = malloc((arr_len * 2 + 1) * sizeof *string);//the sizeof *string is optional
        if (string == NULL)
            return NULL;
        string[0] = '\0';//clear first char, just in case
        for (int i=0;i<arr_len;++i)
            snprintf(string + i*2, 3, "%02x", arr[i]);//same as before
        string[arr_len*2] = '\0';//optional, just a habit of mine
        return string;//return string
    }
    
    int main( void )
    {
        int array[] = {12, 32, 54, 1, 6};
        char *as_string = get_hex_string(array, sizeof array/sizeof *array);
        if (as_string == NULL)
        {
            fprintf(stderr, "Failed to get hex-string\n");
            exit( EXIT_FAILURE );
        }
        printf("Hex-string: %s\n", as_string);
        free(as_string);//optional here, but good habit
        return EXIT_SUCCESS;
    }
    

    Demo

    【讨论】:

      【解决方案3】:

      有点不清楚你为什么写array2[0],这意味着array2应该是一个字符串数组,声明如下:

      char array2[N][M];
      

      其中 N 至少为 1,M 至少为 6 以保持 "apple\0"

      如果你的意思是 array2 应该是一个字符串,声明如下:

      char array2[32];
      

      例如,您可以通过从array1 复制字符然后在末尾添加'\0' 字符来结束字符串:

      memcpy(array2, array1, 5);
      array2[5] = '\0';
      

      此时,做例如printf("'%s'\n", array2); 将打印 'apple'

      【讨论】:

        【解决方案4】:

        如果我理解正确,那么二维数组的定义如下所示

        char a[M][N] = { "apple" };
        

        其中 M 和 N 是一些指定数组大小的整数常量。 (在 C 中,如果编译器支持,您也可以使用可变长度数组)

        或者如果你想复制上面定义的二维数组的第一个元素中的第一个数组,那么你需要编写

        memcpy( a[0], array1, 5 );
        a[0][5] = '\0';
        

        如果 array1 包含一个以零结尾的字符串,那么您可以使用 strcpy 而不是 memcpy

        注意 我想你的意思是例如

        array1[0] = 'a';
        

        而不是

        array1[0] = "a"
        

        如果是这样,那么代码可能看起来像

        #include <stdio.h>
        #include <string.h>
        
        
        int main(void) 
        {
            char array1[5];
            char array2[10][6];
        
            array1[0] = 'a';
            array1[1] = 'p';
            array1[2] = 'p';
            array1[3] = 'l';
            array1[4] = 'e';
        
            memcpy( array2[0], array1, 5 );
            array2[0][5] = '\0';
        
            printf( "array2[0] = %s\n", array2[0] );
        
            return 0;
        }
        

        否则如果array1本身是一个二维数组,那么你应该使用标准函数strcat,代码可能看起来像

        #include <stdio.h>
        #include <string.h>
        
        int main(void) 
        {
            char array1[5][2] = { "a", "p", "p", "l", "e" };
            char array2[10][6] = { { '\0' } };
        
            for ( int i = 0; i < 5; i++ ) strcat( array2[0], array1[i] );
        
            printf( "array2[0] = %s\n", array2[0] );
            return 0;
        }
        

        在这两种情况下,输出都是

        apple
        

        或者如果第二个数组是一维数组,那么你可以写

        #include <stdio.h>
        #include <string.h>
        
        int main(void) 
        {
            char array1[5][2] = { "a", "p", "p", "l", "e" };
            char string[6] = { '\0' };
        
            for ( int i = 0; i < 5; i++ ) strcat( string, array1[i] );
        
            printf( "string = %s\n", string );
            return 0;
        }
        

        【讨论】:

        • 我认为最后一个例子是我需要的,但它目前有段错误。
        • @Jasper Kanbier 您的段错误与我展示的代码示例没有任何共同之处。也许你忘了用零初始化目标字符串。
        【解决方案5】:

        这应该适合你:

        #include <stdio.h>
        #include <string.h>
        
        #define MAX_SIZE 6
        
        int main() {
        
            char array1[MAX_SIZE];
            char array2[1][MAX_SIZE];
        
            array1[0] = 'a';
            array1[1] = 'p';
            array1[2] = 'p';
            array1[3] = 'l';
            array1[4] = 'e';
            //...
        
        
            array1[MAX_SIZE-1] = '\0';
        
            strcpy(array2[0], array1);
        
            array2[0][MAX_SIZE-1] = '\0';
        
            printf("%s", array2[0]);
        
            return 0 ;
        
        }
        

        【讨论】:

        • 一个字符串需要空终止,array1中没有空终止!
        • 错误,因为您需要 6 个char 来存储"apple"!所以strcpy() 会给出未定义的行为。
        • 好吧,不过苹果只是一个例子,array1 的内容会在 while 循环中发生变化。
        • @BrianSidebotham,意义重大,Jasper Kanbier 更新了我的答案!
        • @Rizier123 在我的代码中,array1 是while 循环的一部分,而且内容在变化,实际上是成千上万的水果..;-) 所以转换需要成为循环的一部分。跨度>
        猜你喜欢
        • 1970-01-01
        • 2023-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-07
        • 2023-03-31
        • 2019-01-18
        相关资源
        最近更新 更多