为文件附加不重复的随机文本(C)

时间:2015-10-27 07:14:24

标签: c file random

我有5个名单

char *name[] = {"a","b","c","d","e"};

我有3个文件

char path1[PATH_MAX+1]
snprintf(path1, PATH_MAX+1, "%sfile1.txt",dirname);
FILES *filename1 = fopen(path1, "w")
.
.
.
char path3[PATH_MAX+1]
snprintf(path3, PATH_MAX+1, "%sfile3.txt",dirname);
FILES *filename3 = fopen(path3, "w")

我想要的是随机将 a,b,c,d,e (每个文件中的一个)附加到其中三个文件中而不重复。

我现在拥有的是(其中一个示例)

srand(time(NULL));
int one = rand()%5;
char path1[PATH_MAX+1];
snprintf(path1, PATH_MAX+1, "%sfile1.txt",dirname);
FILES *filename1 = fopen(path1, "w");
fputs(name[one],filename1);
fclose(filename1);

但是,有时我的 file1.txt file3.txt 都包含 b (同样的字母表来自名)

问题

我是否遗漏了一些内容以确保所有随机结果始终是唯一的?

有6行代码创建一个文件并在其中附加一个随机名称也是有效的吗?我只是想知道我是否需要创建20个文件,我会写出基本上几乎相同的120行,数量不同(文件名 1 到文件名 3

谢谢。

1 个答案:

答案 0 :(得分:1)

要获得一个独特的字符序列,您可以从逐渐减少的池中绘制它们。例如,在您选择a之后,它将从池中删除。当然,池必须至少与要打印的文件数一样大。

实现这种选择的一种简单方法是从池中选择一个字符,将最后一个字符从池中移动到拾取字符的位置,并将池大小减小一个。

如果你看到很多重复的代码,特别是如果唯一的区别是filename1filename2filename3等行的变量名称,那么应该响铃您应该使用数组:FILE *file[NFILE]。但请注意,您一次只能打开一定数量的文件。

在您的情况下,您希望将单个字符写入文件。不需要同时打开多个文件:打开文件,选择一个字符,将其写入文件,关闭e文件。然后处理下一个文件。

我认为下面的程序可以满足您的需求。

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

#define NFILES 10

int main()
{
    char pool[] = "abcdefghij";     // Available chars as array
    int npool = sizeof(pool) - 1;   // Pool size minus terminating '\0'
    int i;

    if (npool < NFILES) {
        fprintf(stderr,
            "Not enough letters in pool for %d files.\n", NFILES);
        exit(1);
    }

    srand(time(NULL));

    for (i = 0; i < NFILES; i++) {
        int ipick = rand() % npool;    // position of pick
        char pick = pool[ipick];       // picked char

        char fname[20];
        FILE *f;

        pool[ipick] = pool[--npool];   // remove pick from pool

        snprintf(fname, sizeof(fname), "file-%03d.txt", i);

        f = fopen(fname, "w");
        if (f == NULL) {
            fprintf(stderr, "Could not create %s.\n", fname);
            exit(1);
        }

        fprintf(f, "%c\n", pick);
        fclose(f);
    }

    return 0;
}