С++ в относительно новых стандартах

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: С++ в относительно новых стандартах

Непрочитанное сообщение Olej » 29 дек 2020, 00:06

Olej писал(а):
28 дек 2020, 19:31
А ещё лучше (нагляднее) это можно сделать так:
И, похоже, что уровни оптимизации GCC не разрушают характер зависимостей ... или это мне только кажется?:

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs$ g++ -O0 rvalue2.cc -o rvalue2

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs$ ./rvalue2 60 10000000
время 0 = 0.497317 секунд       + : (60) mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
время 1 = 0.457987 секунд       + : (60) mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
время 2 = 0.45403 секунд        + : (60) mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
время 3 = 0.153536 секунд       + : (60) mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs$ g++ -O3 rvalue2.cc -o rvalue2

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs$ ./rvalue2 60 10000000
время 0 = 0.355857 секунд       + : (60) mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
время 1 = 0.336972 секунд       + : (60) mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
время 2 = 0.316174 секунд       + : (60) mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
время 3 = 0.0461078 секунд      + : (60) mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: С++ в относительно новых стандартах

Непрочитанное сообщение Olej » 30 дек 2020, 00:58

Реально возникшая задача в проекте: нагенерить в (текущем) каталоге много файлов разного (случайного) размера с именами из списка, построчно заданного в файле данных ... не создавать же эту сотню-другую файлов вручную?!
Содержимое что будет в этих файлах - не важно, они будут тестироваться в групповой передаче по сети.
Список файлов в простейшем виде выглядит так, построчно:

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii$ cat list.dat 
file.1
file.2
file.3
Только реально там сотня или две...

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: С++ в относительно новых стандартах

Непрочитанное сообщение Olej » 30 дек 2020, 01:02

Olej писал(а):
30 дек 2020, 00:58
нагенерить в (текущем) каталоге много файлов разного (случайного) размера с именами из списка
Вариант 1: с реальным энтропийным генератором случайных чисел из /dev/urandom :

Код: Выделить всё

#include <iostream>     // std::cout
#include <functional>   // std::bind
#include <fstream>
#include <chrono>
#include <random>
#include <iterator>
#include <unistd.h>
using namespace std;

const int limit = 100000;         // max files length
random_device rd;                 // produces non-deterministic random numbers, if supported
const size_t divider = rd.max() / limit;

int main( int argc, char *argv[] ) {
   bool debug = false;
    char c;
    while( -1 != ( c = getopt( argc, argv, "v" ) ) )
        if( 'v' == c ) debug = true;                     // debug output: ON
        else return 1;
    if( argc != optind + 1 )
    {
        cerr << "usage: [-v] " << argv[ 0 ] << " <file_list_names>" << endl;
        exit( EXIT_FAILURE );
    }
    ifstream fin;
    fin.open( argv[ optind ] );
    if( !fin ) {  
	cerr << "such file not found" << endl;
	return 1;
    }
    while (fin)
    {
	string line;
	getline( fin, line );
	if( line.empty() ) continue;
	ofstream fou( line );
	ostream_iterator<char> oi( fou, "" );
	size_t length = rd() / divider;
        if (debug)
            cout << line << " : " << length << endl;
	for (size_t i = 0; i < length; i++)
	    *oi++ = '0';
	fou << flush;
	fou.close();
    } 
    return 0;
}
P.S. Про генераторы случайных чисел в Linux (с точки зрения системы и аппаратуры, а не C++) у нас тут была уже развёрнутая тема: генератор случайных чисел
Вложения
make_dii_group_r.cc
(1.21 КБ) 58 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: С++ в относительно новых стандартах

Непрочитанное сообщение Olej » 30 дек 2020, 01:06

Olej писал(а):
30 дек 2020, 01:02
Вариант 1: с реальным энтропийным генератором случайных чисел из /dev/urandom :
Но /dev/urandom нет в некоторых системах (всё та же винда), да и на некоторых аппаратных реализациях Linux...
Вариант 2: используется псевдослучайный генератор:

Код: Выделить всё

#include <iostream>
#include <iostream>     // std::cout
#include <functional>   // std::bind
#include <fstream>
#include <chrono>
#include <random>
#include <iterator>
#include <unistd.h>
using namespace std;

const int limit = 100000;                                // max files length
// https://www.cplusplus.com/reference/random/
// construct a trivial random generator engine from a time-based seed:
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator( seed );            // default_random_engine generator;
uniform_int_distribution<int> distribution( 0, limit );  // generates pseudo-random numbers
auto dice = std::bind( distribution, generator );

int main( int argc, char *argv[] ) {
    bool debug = false;
    char c;
    while( -1 != ( c = getopt( argc, argv, "v" ) ) )
	if( 'v' == c ) debug = true;			 // debug output: ON
	else return 1;
    if( argc != optind + 1 ) 
    {
	cerr << "usage: [-v] " << argv[ 0 ] << " <file_list_names>" << endl;
	exit( EXIT_FAILURE );
    }
    ifstream fin;
    fin.open( argv[ optind ] );
    if( !fin ) {  
	cerr << "such file not found" << endl;
	return 1;
    }
    while (fin)
    {
	string line;
	getline( fin, line );
	if( line.empty() ) continue;
	ofstream fou( line );
	ostream_iterator<char> oi( fou, "" );
	size_t length = dice();
	if (debug)
	    cout << line << " : " << length << endl;
	for (size_t i = 0; i < length; i++)
	    *oi++ = '0';
	fou.close();
    } 
    return 0;
}
P.S. URL справочной системы <random> показаны комментариями - там можно на выбор выбрать множество разных псевдослучайных генераторов, на любой вкус.
Вложения
make_dii_group_p.cc
(1.47 КБ) 88 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: С++ в относительно новых стандартах

Непрочитанное сообщение Olej » 30 дек 2020, 01:11

Olej писал(а):
30 дек 2020, 00:58
нагенерить в (текущем) каталоге много файлов разного (случайного) размера
И теперь всё это хозяйство проверяем в деле:

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii$ make
g++ -Wall -O0 -DDEBUG     make_dii_group_p.cc   -o make_dii_group_p
g++ -Wall -O0 -DDEBUG     make_dii_group_r.cc   -o make_dii_group_r

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii$ ./make_dii_group_p -v list.dat 
file.1 : 54875
file.2 : 57253
file.3 : 23741

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii$ ./make_dii_group_r -v list.dat 
file.1 : 13576
file.2 : 78862
file.3 : 85489
И убеждаемся, что это "действительно очень случайные размеры", не повторяющиеся от запуска к запуску (как делают простейшие random-генераторы):

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii$ ./make_dii_group_p -v list.dat 
file.1 : 46602
file.2 : 14249
file.3 : 83415

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii$ ./make_dii_group_r -v list.dat 
file.1 : 67274
file.2 : 10104
file.3 : 97821

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: С++ в относительно новых стандартах

Непрочитанное сообщение Olej » 31 дек 2020, 01:51

Olej писал(а):
30 дек 2020, 01:11
И теперь всё это хозяйство проверяем в деле:
Более развёрнутые (практичные) варианты на сегодня, соответственно:
- file_group_r.cc - аппаратный, энтропийный, случайны генератор:

Код: Выделить всё

#include <iostream>                // std::cout
#include <functional>              // std::bind
#include <fstream>
#include <chrono>
#include <random>
#include <iterator>
#include <experimental/filesystem> // https://en.cppreference.com/w/cpp/experimental/fs/create_directory
namespace fs = std::experimental::filesystem;
#include <unistd.h>
using namespace std;

void help( const char *prg )
{
    cout << "usage: [-l <max_length>][-d <dirctory>][-v] " << prg << " <file_names_list>" << endl;
}

int main( int argc, char *argv[] ) 
{
    bool debug = false;
    size_t limit = 100000;             // max files length
    string dir( "." );
    const char *switches = "d:l:v";    // exec options
    char c;
    while ( ( c = getopt( argc, argv, switches  ) ) != -1 ) {
        switch( c ) {
            case 'd' :
                dir = string( optarg );
                if ( ! fs::is_directory( dir.c_str() ) )
                {
                    if( ! fs::create_directory( dir.c_str() ) )
                        cout << "create directory error: " << dir << endl;
                    else
                        cout << "create new directory: " << dir << endl;
                }
                break;
            case 'l' : if ( atol( optarg ) > 0 ) limit = atol( optarg ); break;
            case 'v' : debug = true; break;
            default  : help( argv[ 0 ] ); exit( EXIT_FAILURE );
       }
    }
    random_device rd;                  // produces non-deterministic random numbers, if supported
    const size_t divider = rd.max() / limit;
    if( argc != optind + 1 )
    {
        help( argv[ 0 ] );
        exit( EXIT_FAILURE );
    }
    ifstream fin;
    fin.open( argv[ optind ] );
    if ( !fin )
    {
        cerr << "such file not found: " << argv[ optind ] << endl;
        return EXIT_FAILURE;
    }
    while ( fin )
    {
	string line;
	getline( fin, line );
	if( line.empty() ) continue;
        string path = dir + "/" + line;
        ofstream fou( dir + "/" + line );
        if( !fou )
        {
            cerr << "create file error: " << path << endl;
            continue;
	}
	ostream_iterator<char> oi( fou, "" );
	size_t length = rd() / divider;
        if (debug)
            cout << path << " : " << length << endl;
	for (size_t i = 0; i < length; i++)
	    *oi++ = '0';
	fou.close();
    } 
    return 0;
}
- file_group_p.cc - псевдослучайный генератор:

Код: Выделить всё

#include <iostream>                // std::cout
#include <functional>              // std::bind
#include <fstream>
#include <chrono>
#include <random>
#include <iterator>
#include <experimental/filesystem> // https://en.cppreference.com/w/cpp/experimental/fs/create_directory
namespace fs = std::experimental::filesystem;
#include <unistd.h>
using namespace std;

void help( const char *prg )
{
    cout << "usage: [-l <max_length>][-d <dirctory>][-v] " << prg << " <file_names_list>" << endl;
}

int main( int argc, char *argv[] ) 
{
    bool debug = false;
    size_t limit = 100000;             // max files length
    string dir( "." );
    const char *switches = "d:l:v";    // exec options
    char c;
    while ( ( c = getopt( argc, argv, switches  ) ) != -1 ) {
	switch( c ) {
            case 'd' :
                dir = string( optarg );
                if ( ! fs::is_directory( dir.c_str() ) )
                {
                    if( ! fs::create_directory( dir.c_str() ) )
                        cout << "create directory error: " << dir << endl;
		    else
			cout << "create new directory: " << dir << endl;
		}
                break;
	    case 'l' : if ( atoi( optarg ) > 0 ) limit = atoi( optarg ); break;
	    case 'v' : debug = true; break;
	    default  : help( argv[ 0 ] ); exit( EXIT_FAILURE );
       }
    }
    // https://www.cplusplus.com/reference/random/
    // construct a trivial random generator engine from a time-based seed:
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    std::default_random_engine generator( seed );            // default_random_engine generator;
    uniform_int_distribution<long> distribution( 0, limit ); // generates pseudo-random numbers
    auto dice = std::bind( distribution, generator );
    if( argc != optind + 1 ) 
    {
	help( argv[ 0 ] );
	exit( EXIT_FAILURE );
    }
    ifstream fin;
    fin.open( argv[ optind ] );
    if ( !fin )
    {  
	cerr << "such file not found: " << argv[ optind ] << endl;
	return EXIT_FAILURE;
    }
    while ( fin )
    {
	string line;
	getline( fin, line );
	if( line.empty() ) continue;
	string path = dir + "/" + line;
	ofstream fou( dir + "/" + line );
        if( !fou )
	{
	    cerr << "create file error: " << path << endl;
	    continue;
	}
	ostream_iterator<char> oi( fou, "" );
	size_t length = dice();
	if (debug)
	    cout << path << " : " << length << endl;
	for (size_t i = 0; i < length; i++)
	    *oi++ = '0';
	fou.close();
    } 
    return EXIT_SUCCESS;
}
Вложения
file_group_r.cc
(2.29 КБ) 73 скачивания
file_group_p.cc
(2.45 КБ) 54 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: С++ в относительно новых стандартах

Непрочитанное сообщение Olej » 31 дек 2020, 01:54

Olej писал(а):
31 дек 2020, 01:51
Более развёрнутые (практичные) варианты на сегодня, соответственно:
Теперь здесь можно задать масштаб, лимит размера создаваемых файлов, отладочный вывод и, самое главное, каталог в котором создавать (группировать) файлы:

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii$ ./file_group_p -v -d123 -l1000 list.dat
123/file.1 : 798
123/file.2 : 478
123/file.3 : 222

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii$ ./file_group_r -v -d123 -l1000 list.dat
123/file.1 : 386
123/file.2 : 276
123/file.3 : 379

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii$ ./file_group_r -v -d123 -l1000 list.dat
123/file.1 : 331
123/file.2 : 309
123/file.3 : 627

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii$ ./file_group_r -v -d123 -l1000 list.dat
123/file.1 : 194
123/file.2 : 353
123/file.3 : 663

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: С++ в относительно новых стандартах

Непрочитанное сообщение Olej » 31 дек 2020, 01:59

Olej писал(а):
30 дек 2020, 00:58
Реально возникшая задача в проекте: нагенерить в (текущем) каталоге много файлов разного (случайного) размера с именами из списка
Загружаю на боевой удалённый сервер на котором это должно тестироваться и выполняться и ...:

Код: Выделить всё

oleg.tsiliuric@zodiac-ctec-1:/home/nfs_builds/Olej/wb20emu$ ./b1_b2_files/file_group_r -d./1234 -l1000 b_list.dat
./b1_b2_files/file_group_r: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./b1_b2_files/file_group_r)
./b1_b2_files/file_group_r: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by ./b1_b2_files/file_group_r)
./b1_b2_files/file_group_r: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./b1_b2_files/file_group_r)
Облом-с!
Перекомпилирую на месте:

Код: Выделить всё

oleg.tsiliuric@zodiac-ctec-1:/home/nfs_builds/Olej/wb20emu/b1_b2_files$ make
g++ -Wall -std=c++11 file_group_p.cc -lstdc++fs -o file_group_p
file_group_p.cc:7:105: fatal error: experimental/filesystem: No such file or directory
 #include <experimental/filesystem> // https://en.cppreference.com/w/cpp/experimental/fs/create_directory
                                                                                                         ^
compilation terminated.
make: *** [file_group_p] Error 1
Вот так! - ещё раз облом!
А потому что на этом сервере общего пользования:

Код: Выделить всё

oleg.tsiliuric@zodiac-ctec-1:/home/nfs_builds/Olej/wb20emu/b1_b2_files$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
А отрабатывалось это на моём домашнем рабочем компьютере:

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii$ g++ --version
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Вот и такие бывают засады! :-o

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: С++ в относительно новых стандартах

Непрочитанное сообщение Olej » 31 дек 2020, 18:33

Olej писал(а):
31 дек 2020, 01:59
Вот и такие бывают засады!
Тогда всё это (проверка существования и создание при необходимости каталогов) будем делать по-старинке через POSIX API Linux...

- file_group_r.cc - аппаратный, энтропийный, случайны генератор:

Код: Выделить всё

#include <iostream>                // std::cout
#include <functional>              // std::bind
#include <fstream>
#include <chrono>
#include <random>
#include <iterator>
#include <cstring>
using namespace std;
#include <unistd.h>
#include <sys/stat.h>

bool debug = false; // debug messages ON

int test_dir( char* path )
{
    struct stat st;
    if ( stat( path, &st ) == 0 )
    {
	if ( S_ISDIR( st.st_mode ) ) 
	    return 0;
    }
    if (debug) cout << "create new directory: " << path << endl;
    int ret;
    for (char* p = strchr(path + 1, '/'); ; p = strchr(p + 1, '/')) {
        if (p) *p = '\0';
        if ((ret = mkdir(path, 0755)) == -1)
            if (errno != EEXIST) 
		break;
        if (p) *p = '/';
        else break;
    }
    return ret;
}

void help( const char *prg )
{
    cout << "usage: [-l <max_length>][-d <dirctory>][-v] " << prg << " <file_names_list>" << endl;
}

int main( int argc, char *argv[] ) 
{
    size_t limit = 100000;             // max files length
    string dir( "." );
    const char *switches = "d:l:v";    // exec options
    char c;
    while ( ( c = getopt( argc, argv, switches  ) ) != -1 ) {
        switch( c ) {
            case 'd' :
                dir = string( optarg );
		if ( test_dir( (char*)dir.c_str() ) != 0 )
		{
                    cerr << "create directory error: " << dir << endl;
		    exit( EXIT_FAILURE );
		}
                break;
            case 'l' : if ( atol( optarg ) > 0 ) limit = atol( optarg ); break;
            case 'v' : debug = true; break;
            default  : help( argv[ 0 ] ); exit( EXIT_FAILURE );
       }
    }
    random_device rd;                  // produces non-deterministic random numbers, if supported
    const size_t divider = rd.max() / limit;
    if( argc != optind + 1 )
    {
        help( argv[ 0 ] );
        exit( EXIT_FAILURE );
    }
    ifstream fin;
    fin.open( argv[ optind ] );
    if ( !fin )
    {
        cerr << "such file not found: " << argv[ optind ] << endl;
        return EXIT_FAILURE;
    }
    while ( fin )
    {
	string line;
	getline( fin, line );
	if( line.empty() ) continue;
        string path = dir + "/" + line;
        ofstream fou( dir + "/" + line );
        if( !fou )
        {
            cerr << "create file error: " << path << endl;
            continue;
	}
	ostream_iterator<char> oi( fou, "" );
	size_t length = rd() / divider;
        if (debug)
            cout << path << " : " << length << endl;
	for (size_t i = 0; i < length; i++)
	    *oi++ = '0';
	fou.close();
    } 
    return 0;
}
- file_group_p.cc - псевдослучайный генератор:

Код: Выделить всё

#include <iostream>                // std::cout
#include <functional>              // std::bind
#include <fstream>
#include <chrono>
#include <random>
#include <iterator>
#include <cstring>
using namespace std;
#include <unistd.h>
#include <sys/stat.h>

bool debug = false; // debug messages ON

int test_dir( char* path )
{
    struct stat st;
    if ( stat( path, &st ) == 0 )
    {
        if ( S_ISDIR( st.st_mode ) )
            return 0;
    }
    if (debug) cout << "create new directory: " << path << endl;
    int ret;
    for (char* p = strchr(path + 1, '/'); ; p = strchr(p + 1, '/')) {
        if (p) *p = '\0';
        if ((ret = mkdir(path, 0755)) == -1)
            if (errno != EEXIST)
                break;
        if (p) *p = '/';
        else break;
    }
    return ret;
}

void help( const char *prg )
{
    cout << "usage: [-l <max_length>][-d <dirctory>][-v] " << prg << " <file_names_list>" << endl;
}

int main( int argc, char *argv[] ) 
{
    bool debug = false;
    size_t limit = 100000;             // max files length
    string dir( "." );
    const char *switches = "d:l:v";    // exec options
    char c;
    while ( ( c = getopt( argc, argv, switches  ) ) != -1 ) {
	switch( c ) {
            case 'd' :
                dir = string( optarg );
                if ( test_dir( (char*)dir.c_str() ) != 0 )
                {
                    cerr << "create directory error: " << dir << endl;
                    exit( EXIT_FAILURE );
                }
                break;
	    case 'l' : if ( atoi( optarg ) > 0 ) limit = atoi( optarg ); break;
	    case 'v' : debug = true; break;
	    default  : help( argv[ 0 ] ); exit( EXIT_FAILURE );
       }
    }
    // https://www.cplusplus.com/reference/random/
    // construct a trivial random generator engine from a time-based seed:
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    std::default_random_engine generator( seed );            // default_random_engine generator;
    uniform_int_distribution<long> distribution( 0, limit ); // generates pseudo-random numbers
    auto dice = std::bind( distribution, generator );
    if( argc != optind + 1 ) 
    {
	help( argv[ 0 ] );
	exit( EXIT_FAILURE );
    }
    ifstream fin;
    fin.open( argv[ optind ] );
    if ( !fin )
    {  
	cerr << "such file not found: " << argv[ optind ] << endl;
	return EXIT_FAILURE;
    }
    while ( fin )
    {
	string line;
	getline( fin, line );
	if( line.empty() ) continue;
	string path = dir + "/" + line;
	ofstream fou( dir + "/" + line );
        if( !fou )
	{
	    cerr << "create file error: " << path << endl;
	    continue;
	}
	ostream_iterator<char> oi( fou, "" );
	size_t length = dice();
	if (debug)
	    cout << path << " : " << length << endl;
	for (size_t i = 0; i < length; i++)
	    *oi++ = '0';
	fou.close();
    } 
    return EXIT_SUCCESS;
}

Вложения
file_group_r.cc
(2.49 КБ) 54 скачивания
file_group_p.cc
(2.8 КБ) 59 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: С++ в относительно новых стандартах

Непрочитанное сообщение Olej » 31 дек 2020, 18:44

Olej писал(а):
31 дек 2020, 18:33
Тогда всё это (проверка существования и создание при необходимости каталогов) будем делать по-старинке через POSIX API Linux...
Теперь оно может (если уж переделывать, так так чтоб не напрасно :lol: ):
- создавать каталоги рекурсивно (опция -d), например ./1/2/3
- определять диапазон максимальной длины файлов (опция -l)
- разрешать (-v) или нет диагностический вывод того что делает

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii/C++11$ make
g++ -Wall -std=c++11 file_group_p.cc -o file_group_p
g++ -Wall -std=c++11 file_group_r.cc -o file_group_r

Код: Выделить всё

- по несуществующим каталогам (создание):
olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii/C++11$ ./file_group_r -v -d4/3/4/5 -l100 list.dat
create new directory: 4/3/4/5
4/3/4/5/file.1 : 87
4/3/4/5/file.2 : 40
4/3/4/5/file.3 : 5
- по существующим каталогам (использование):

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii/C++11$ ./file_group_r -v -d4/3/4/5 -l100 list.dat
4/3/4/5/file.1 : 33
4/3/4/5/file.2 : 52
4/3/4/5/file.3 : 3

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii/C++11$ tree 4
4
└── 3
    └── 4
        └── 5
            ├── file.1
            ├── file.2
            └── file.3

3 directories, 3 files

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii/C++11$ ls -l 4/3/4/5
итого 12
-rw-rw-r-- 1 olej olej 33 дек 31 16:00 file.1
-rw-rw-r-- 1 olej olej 52 дек 31 16:00 file.2
-rw-rw-r-- 1 olej olej  3 дек 31 16:00 file.3

Код: Выделить всё

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii/C++11$ ./file_group_p -d4/3/4/5 -l100 list.dat

olej@nvidia:~/2020_WORK/Zodiac_Systems/OWN-DRAFT-TESTs/make_dii/C++11$ ls -l 4/3/4/5
итого 12
-rw-rw-r-- 1 olej olej 27 дек 31 16:31 file.1
-rw-rw-r-- 1 olej olej 62 дек 31 16:31 file.2
-rw-rw-r-- 1 olej olej 70 дек 31 16:31 file.3
- видно, что размеры при каждом запуске меняются!

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 14 гостей