shuffle
あると便利なんだけどなんか見つからなかったコマンド。shuffle
標準入力を行毎にシャッフルするようなコマンド。
ありそうなんだけどなぁ...
無かったので作ってみた↓
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <unistd.h> #include <assert.h> #include <unistd.h> #include <getopt.h> //Listは循環リスト typedef struct _List { struct _List* next; char* str; } List; int main ( int argc, char* argv[] ) { //乱数にseedをあたえる timeval tv; gettimeofday( &tv , NULL ); unsigned int seed = tv.tv_usec; while( 1 ) { static struct option longopts[] = { { "seed", required_argument, NULL, 's' }, { 0, 0, 0, 0 } }; int c = getopt_long( argc, argv, "s:", longopts, NULL ); if( c == -1 ) { break; } switch( c ) { case 's': seed = atoi( optarg ); break; default: return -1; } } srand( seed ); //ファイル(もしくは標準入力)を開く FILE* fp = stdin; if( optind + 1 == argc ) { fp = fopen( argv[optind], "r" ); if( fp == NULL ) { return 1; } } //読み込み List* list_cur = NULL; char* line = NULL; size_t len = 0; int lings = 0; while( getline( &line, &len, fp ) != -1 ) { lings++; if( list_cur == NULL ) { //リングリスト作成 list_cur = (List*)malloc( sizeof( List ) ); if( list_cur == NULL ) { free( line ); break; } list_cur->next = list_cur; list_cur->str = line; } else { //リングリスト挿入 List* newNode = (List*)malloc( sizeof( List ) ); if( list_cur == NULL ) { free( line ); break; } newNode->next = list_cur->next; newNode->str = line; list_cur->next = newNode; } //lineにNULLを代入しないとgetlineでreallocされてしまう line = NULL; //リングを回す。 for( int i = 0; i < ( (double)lings * rand() ) / ( RAND_MAX + 1.0 ); i++ ) { list_cur = list_cur->next; } } //XXX:getlineはEOFで終了したのかエラーで終了したのか? //リングが空ではない if( list_cur != NULL ) { //getlineでallocされたメモリとリスト用のメモリの開放 //list_nextはfreeされたメモリを参照しないためのテンポラリ //ついでに出力(ついでかよ List* list_next = list_cur->next; list_cur->next = NULL; //リングを切る list_cur = list_next; while( list_cur != NULL ) { list_next = list_cur->next; printf( "%s", list_cur->str ); free( list_cur->str ); free( list_cur ); list_cur = list_next; } } return 0; }
せっかくC++なのに殆どCと言う...。ってかこれCでコンパイル通る気がしてきた...。
ん〜STLとか使えるようになりたいなぁ...。
まぁ、これ作ったのかなり前なんで(と言い訳してみる。
"-s"でシードを与えられるので同じ入力与えられれば、同じ結果を返すようにもできます。
まぁ、地味に有用。
mplayerとかシャッフル機能の無いプレーヤなんかでシャッフルしたい場合なんかに、プレイリストファイル自体をシャッフル(w
ということで今回も無駄に長くなったのでここまでノシ