Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
365 views
in Technique[技术] by (71.8m points)

Append Random Text without Repetition for File (C)

I have 5 list of name

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

and I have 3 files

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")

What I want is to randomly append a,b,c,d,e (one of them per file) into three of those files without repetition.

What I have right now is (example from one of them)

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);

However, sometimes it is still possible where my file1.txt and file3.txt both contain b (same alphabet from name)

Questions

Did I miss something to make sure that all the random result always unique?

Is it also efficient tho to have 6 lines of code to create one file and append a random name inside it? I'm just wondering if I have to create like 20 files, I will write 120 lines that basically almost the same, just different in number (filename1 to filename3)

Thank you.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To get a unique sequence of characters, you can draw them from a diminishing pool. For example, after you have picked the a, it is removed from the pool. Of course, the pool must be at least as big as the number of files you want to print.

A simple way to implement this sort of picking is to pick a char from the pool, move the last character from the pool to the place of the picked character and decrease the pool size by one.

If you see a lot of repetition of code, especially if the only difference is a variable name along the lines of filename1, filename2, filename3 and so on should ring a bell that you should use an array: FILE *file[NFILE]. Be aware, though, that you can only have a certain number of files open at a time.

In your case, you want to write a single character to a file. There's no need to have multiple file s open simultaneously: Open a file, pick a char, write it to the file, close e file. Then process the next file.

The program below does what you want, I think.

#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 ''
    int i;

    if (npool < NFILES) {
        fprintf(stderr,
            "Not enough letters in pool for %d files.
", 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.
", fname);
            exit(1);
        }

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

    return 0;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...