交换字符串数组中的元素

时间:2017-02-14 00:28:48

标签: c arrays string

我正在尝试创建一个程序来生成随机测试用例。我有一个有序的字符串数组(char **),我想将它们随机化。我的方法是随机选择两个元素并交换它们。但是我不断遇到一个段错误,似乎错过了一些知识。

示例数组(64个元素):{"1 2 3", "3 2 1", "4 5 6".....}

char ** randomizeOrder(char ** list, int size){

    char temp[6];
    temp[5] = '\0';

    srand(time(NULL));
    int count = 64;
    int x, y;
    while(count > 0){
        fprintf(stderr, "Starting...\n");
        x = rand() % 64;
        y = rand() % 64;

        strcpy(temp, list[x]);
        fprintf(stderr, "Copying %s from Y to X\n", list[y]);
        strcpy(list[x], list[y]);
        fprintf(stderr, "Copying %s from temp to Y\n", temp);
        strcpy(list[y], temp);
        count--;
    }

    return list;

}

它似乎适用于前几个元素,然后开始阅读垃圾。元素是malloc'ed和数组一样,所有元素都打印得很好。任何想法都出错了?

3 个答案:

答案 0 :(得分:4)

认为你应该只交换指针,而不是字符串内容本身。 char**当然只是一个指针数组。

看起来像这样:

while(count > 0){
    x = rand() % 64;
    y = rand() % 64;

    char* tmp = list[x];
    list[x] = list[y];
    list[y] = tmp;
    count--;
}

如果你想变得聪明,可以使用this trick

while(count > 0){
    x = rand() % 64;
    y = rand() % 64;

    list[x] |= list[y];
    list[y] |= list[x];
    list[x] |= list[y];

    count--;
}

答案 1 :(得分:1)

我相信他们的代码中存在一些问题:

  • 您将size传递给randomize(),但您从未使用过它。最好这样做:

    size_t x = rand() % size;
    size_t y = rand() % size;
    

    而不是将64的大小值硬编码到这些行中。

  • 由于您正在交换指针,因此无需创建临时缓冲区和strcpy()指针。你可以简单地交换指针本身。我建议只使用这样的函数:

    void swap(char **s1, char **s2) {
        char *temp = *s1;
        *s1 = *s2;
        *s2 = temp;
    }
    

    然后你可以简单地通过swap(&list[x], &list[y]);交换你的指针。

  • 我不相信您的功能randomize()需要返回char**。如果它只是void会更容易。

以下是一些测试代码,显示了这一点:

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

#define ARRAYSIZE(x) (sizeof x / sizeof x[0])

void randomize(char **list, size_t size);
void print_list(char **list, size_t size);
void swap(char **s1, char **s2);

int main(void) {
    char *list[] = {"1 2 3", "3 2 1", "4 5 6", "6 5 4", "7 8 9", "9 8 7"};

    printf("Original list:\n");
    print_list(list, ARRAYSIZE(list));

    randomize(list, ARRAYSIZE(list));

    return 0;
}

void randomize(char **list, size_t size) {
    size_t x, y;

    srand(time(NULL));

    for (size_t i = 0; i < size; i++) {
        x = rand() % size;
        y = rand() % size;

        swap(&list[x], &list[y]);

        printf("Swapping list[%zu] and list[%zu]:\n", x, y);
        print_list(list, size);
    }
}

void print_list(char **list, size_t size) {

    printf("{");
    for (size_t i = 0; i < size-1; i++) {
        printf("%s, ", list[i]);
    }
    printf("%s}\n\n", list[size-1]);
}

void swap(char **s1, char **s2) {
    char *temp = *s1;
    *s1 = *s2;
    *s2 = temp;
}

随机输出:

Original list:
{1 2 3, 3 2 1, 4 5 6, 6 5 4, 7 8 9, 9 8 7}

Swapping list[0] and list[4]:
{7 8 9, 3 2 1, 4 5 6, 6 5 4, 1 2 3, 9 8 7}

Swapping list[4] and list[1]:
{7 8 9, 1 2 3, 4 5 6, 6 5 4, 3 2 1, 9 8 7}

Swapping list[0] and list[1]:
{1 2 3, 7 8 9, 4 5 6, 6 5 4, 3 2 1, 9 8 7}

Swapping list[3] and list[3]:
{1 2 3, 7 8 9, 4 5 6, 6 5 4, 3 2 1, 9 8 7}

Swapping list[2] and list[1]:
{1 2 3, 4 5 6, 7 8 9, 6 5 4, 3 2 1, 9 8 7}

Swapping list[4] and list[1]:
{1 2 3, 3 2 1, 7 8 9, 6 5 4, 4 5 6, 9 8 7}

答案 2 :(得分:0)

您的代码存在的一个问题是,xy可能是相同的数字,而strcpy时您strcpy(list[x], list[y]);自身char**。 Afaik,这不能保证有效。

(虽然我相信您的实际问题可能与您填充输入QStringList filenames = QFileDialog::getOpenFileNames(this,"",QDir::currentPath() ); 的方式有关。无法验证,因为现在缺少信息)