【发布时间】:2020-06-17 13:43:35
【问题描述】:
我需要一些帮助来理解这个 Linux 编程作业。 我必须使用这个 C 程序来随机化一个文本文件,这是程序:
//
// shuffle.c
// Filter that reads every line from stdin (or a specified file),
// shuffles them randomly, and outputs the shuffled lines to stdout.
// This is a partial replacement for the 'shuf' command provided
// with most Linux installations.
// Author: W. Cochran wcochran@wsu.edu
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//
// Seed stdlib's random() with a random
// seed using kernel urandom device.
//
void seedRandom(void) {
FILE *f;
if ((f = fopen("/dev/urandom", "rb")) == NULL) {
perror("/dev/urandom");
exit(-1);
}
unsigned int seed;
fread(&seed, sizeof(seed), 1, f);
fclose(f);
srandom(seed);
}
//
// Fisher–Yates shuffle using stdlib's random()
// https://en.wikipedia.org/wiki/Fisher–Yates_shuffle#Potential_sources_of_bias
// Not really doing this exactly right, see
// https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful
//
void shuffle(int numLines, char *lines[]) {
for (int i = 0; i < numLines-1; i++) {
const int n = numLines - i;
const int j = random() % n + i;
char *tmp = lines[i];
lines[i] = lines[j];
lines[j] = tmp;
}
}
int main(int argc, char *argv[]) {
//
// Read from stdin by default else read from
// first argument specified on command line.
//
FILE *f = stdin;
if (argc >= 2) {
f = fopen(argv[1], "rb");
if (f == NULL) {
perror(argv[1]);
exit(1);
}
}
//
// Buffer each input line into (dynamically sized) array.
// Caveat: Assume lines are less than 200 chars long (I'm too
// lazy to do this right).
//
int capacity = 10;
int numLines = 0;
char **lines = (char **) malloc(capacity * sizeof(char *));
char buf[200];
while (fgets(buf, sizeof(buf), f) != NULL) {
if (numLines >= capacity) {
capacity *= 2;
lines = realloc(lines, capacity * sizeof(char *));
}
lines[numLines++] = strdup(buf);
}
fclose(f);
//
// Seed random number generator used by shuffle.
//
seedRandom();
//
// Shuffle lines.
//
shuffle(numLines, lines);
//
// Echo shuffled lines to stdout.
//
for (int i = 0; i < numLines; i++)
printf("%s", lines[i]);
return 0;
}
作业告诉我以下内容:
我只是需要帮助来解决这一点,拜托。
编译后如何使用shuffle?使用我提供的屏幕截图中刚刚提供的代码有什么意义?
【问题讨论】:
-
它告诉你需要使用
shuffle命令。它可以安装在您的系统上,也可以不安装。如果是,您可以使用它。如果没有安装,老师给了你它的代码,你可以编译使用。 “脚本”会查看是否已安装,如果未安装,则假定它会在当前目录中找到。仅供参考,仅i总是大写,所以I。 -
代码马虎;如果你输入
shuffle file1 file2 file3,它会打乱file1中的文本行并完全忽略file2和file3。所以,该程序的正确用法是shuffle file——它将以打乱的顺序写入文件的行。 -
请注意,引用的 shell 脚本中有一个错误。它读作
1>& 2;空格不正确,重定向应该是1>&2(甚至只是>&2)。 -
最好将 PDF 中的说明转录到问题中,而不是嵌入文本图像。除此之外,该图像在移动设备上是不可读的。
-
@yesitsme :此外,正如您从 C 代码中看到的那样,您可以在不带参数的情况下运行
shuffle,在这种情况下它会处理标准输入。