Ir ao conteúdo
  • Cadastre-se

C++ Criação de multiplos arquivos em c++


Emumaniaco

Posts recomendados

Bom dia.

 

Estou aprendendo c++ na cara e na coragem através de cursos no youtube e livros sobre o assunto e estou começando a fazer meus primeiros programas.

 

Fiz um programa que lista 5 vetores e os distribui em um arranjo que no final me dá um arquivo com 100 mil combinações. Fiquei pensando se seria possível quebrar esse arquivo em 10 partes com 10 mil combinações em cada, mas não achei nenhuma referência dessa situação em lugar nenhum.

 

O resultado final seria uma lista de arquivos (combinacao1.csv, combinacao2.csv, ..., combinacao10.csv)

 

Segue o código abaixo:

#include <iostream>
#include <fstream>

int main()
{
    std::ofstream meuarquivo("combinacao.csv");
    int v0, v1, v2, v3, v4;
    int n=10;
    int total=0;

    std::string vetor00a10[10] = {"1,2,3,6,7", "1,2,3,6,8", "1,2,3,6,9", "1,2,3,6,10", "1,2,3,7,8", "1,2,3,7,9", "1,2,3,7,10", "1,2,3,8,9", "1,2,3,8,10", "1,2,3,9,10"};
    std::string vetor11a20[10] = {"11,12,13,16,17", "11,12,13,16,18", "11,12,13,16,19", "11,12,13,16,20", "11,12,13,17,18", "11,12,13,17,19", "11,12,13,17,20", "11,12,13,18,19", "11,12,13,18,20", "11,12,13,19,20"};
    std::string vetor21a30[10] = {"21,22,23,26,27", "21,22,23,26,28", "21,22,23,26,29", "21,22,23,26,30", "21,22,23,27,28", "21,22,23,27,29", "21,22,23,27,30", "21,22,23,28,29", "21,22,23,28,30", "21,22,23,29,30"};
    std::string vetor31a40[10] = {"31,32,33,36,37", "31,32,33,36,38", "31,32,33,36,39", "31,32,33,36,40", "31,32,33,37,38", "31,32,33,37,39", "31,32,33,37,40", "31,32,33,38,39", "31,32,33,38,40", "31,32,33,39,40"};
    std::string vetor41a50[10] = {"41,42,43,46,47", "41,42,43,46,48", "41,42,43,46,49", "41,42,43,46,50", "41,42,43,47,48", "41,42,43,47,49", "41,42,43,47,50", "41,42,43,48,49", "41,42,43,48,50", "41,42,43,49,50"};

    for (v0=0; v0<n; v0++)
    {
        for (v1=0; v1<n; v1++)
        {
            for (v2=0; v2<n; v2++)
            {
                for (v3=0; v3<n; v3++)
                {
                    for (v4=0; v4<n; v4++)
                    {
                    meuarquivo << vetor00a10[v0] << "," << vetor11a20[v1] << "," << vetor21a30[v2] << "," << vetor31a40[v3] <<  "," << vetor41a50[v4] << std::endl;
                    total++ // Contador
                    }
                }
            }
        }
    }
    meuarquivo.close();

    std::cout << total << std::endl;

	return 0;
}

 

Desde já, obrigado.

 

Fui.

Link para o comentário
Compartilhar em outros sites

Não consegui entender o resultado que conseguiu ou mesmo o que quer conseguir :( 

 

Mas não são 100.000 combinações. Trata-se de uma única combinação.

 

Não entendi porque usar strings para gerar o arquivo e manter as string no programa ao invés de usar os números apenas.

 

E trata-se de um programa em C praticamente. Lembro que C++ tem como gerar permutações em uma única instrução, usando next permutation,  e não precisaria de mais que um vetor. De números.

 

Quanto a dividir o arquivo pode usar esse como entrada e abrir 5 streams e ir gravando o que quer, em um único loop.

 

 

 

Link para o comentário
Compartilhar em outros sites

Como eu disse, estou começando a aprender. Tentei fazer com 'int', mas não consegui fazer a distribuição funcionar. Estou batendo cabeça por dias com coisas que, com certeza, vcs passam o olho e veem a resolução na hora.

 

Citação

Quanto a dividir o arquivo pode usar esse como entrada e abrir 5 streams e ir gravando o que quer, em um único loop

 

Exatamente o que estou dizendo. o conceito eu até entendo. mas os parâmetros do código me fogem completamente.

 

De qualquer forma, obrigado.

 

Fui.

Link para o comentário
Compartilhar em outros sites

Na verdade é um exercício de Análise Combinatória - AC. Mas estava tentando gerar uma calculadora de análise combinatória que vi em visual basic para ser usada no excel (segue arquivo abaixo). Tentei uma aproximação diferente para poder retirar o "lixo" (combinações indesejadas) e me deparei com o seguinte problema: Se você fizer a AC de um número muito grande (milhões de combinações), o excel não vai suportar. Por isso pensei em fazer essa "Calculadora de AC" utilizando colunas dentro de uma matriz com a linguagem de programação que comecei a aprender. Assim poderia fazer a AC não só de números, mas de qualquer coisa que quisesse ('char', 'int' ou 'string' como é o caso).

 

A opção que achei foi separar os resultados em vários arquivos csv ou txt. Tentei fazer com vetores bidimensionais, mas toda vez que compilava, entrava em loop infinito (ainda estou apanhando do parâmetro 'for'). Por isso parti para string.

 

Meu primeiro código (exercício de soma de vetores) foi assim:

 

#include <iostream>
#include <fstream>

int main()
{
    std::ofstream meuarquivo("combinacaosoma.csv");
    int x0, s0;
    int n=10;
    int total=0;

    int soma00a10[10][10] = {{1,1,1,0,0,1,1,0,0,0}, {1,1,1,0,0,1,0,1,0,0}, {1,1,1,0,0,1,0,0,1,0}, {1,1,1,0,0,1,0,0,0,1}, {1,1,1,0,0,0,1,1,0,0}, {1,1,1,0,0,0,1,0,1,0}, {1,1,1,0,0,0,1,0,0,1}, {1,1,1,0,0,0,0,1,1,0}, {1,1,1,0,0,0,0,1,0,1}, {1,1,1,0,0,0,0,0,1,1}};
    int soma11a20[10][10] = {{1,1,1,0,0,1,1,0,0,0}, {1,1,1,0,0,1,0,1,0,0}, {1,1,1,0,0,1,0,0,1,0}, {1,1,1,0,0,1,0,0,0,1}, {1,1,1,0,0,0,1,1,0,0}, {1,1,1,0,0,0,1,0,1,0}, {1,1,1,0,0,0,1,0,0,1}, {1,1,1,0,0,0,0,1,1,0}, {1,1,1,0,0,0,0,1,0,1}, {1,1,1,0,0,0,0,0,1,1}};
    int soma21a30[10][10] = {{1,1,1,0,0,1,1,0,0,0}, {1,1,1,0,0,1,0,1,0,0}, {1,1,1,0,0,1,0,0,1,0}, {1,1,1,0,0,1,0,0,0,1}, {1,1,1,0,0,0,1,1,0,0}, {1,1,1,0,0,0,1,0,1,0}, {1,1,1,0,0,0,1,0,0,1}, {1,1,1,0,0,0,0,1,1,0}, {1,1,1,0,0,0,0,1,0,1}, {1,1,1,0,0,0,0,0,1,1}};
    int soma31a40[10][10] = {{1,1,1,0,0,1,1,0,0,0}, {1,1,1,0,0,1,0,1,0,0}, {1,1,1,0,0,1,0,0,1,0}, {1,1,1,0,0,1,0,0,0,1}, {1,1,1,0,0,0,1,1,0,0}, {1,1,1,0,0,0,1,0,1,0}, {1,1,1,0,0,0,1,0,0,1}, {1,1,1,0,0,0,0,1,1,0}, {1,1,1,0,0,0,0,1,0,1}, {1,1,1,0,0,0,0,0,1,1}};
    int soma41a50[10][10] = {{1,1,1,0,0,1,1,0,0,0}, {1,1,1,0,0,1,0,1,0,0}, {1,1,1,0,0,1,0,0,1,0}, {1,1,1,0,0,1,0,0,0,1}, {1,1,1,0,0,0,1,1,0,0}, {1,1,1,0,0,0,1,0,1,0}, {1,1,1,0,0,0,1,0,0,1}, {1,1,1,0,0,0,0,1,1,0}, {1,1,1,0,0,0,0,1,0,1}, {1,1,1,0,0,0,0,0,1,1}};
    int somatotal[10][10];

    for(x0=0 ; x0<n ; x0++)
    {
        for(s0=0 ; s0<n ; s0++)
        {
            somatotal[x0][s0] = soma00a10[x0][s0] + soma11a20[x0][s0] + soma21a30[x0][s0] + soma31a40[x0][s0] + soma41a50[x0][s0];
        }
    }

    for(x0=0 ; x0<n ; x0++)
    {
        for(s0=0 ; s0<n ; s0++)
        {
            meuarquivo << somatotal[x0][s0] << ",";
            total++;
        }

        meuarquivo << std::endl;

    }

    meuarquivo.close();

    std::cout << total << std::endl;

	return 0;
}

 

A distribuição que eu queria e consegui foi essa:

 

image.png.4dd6e3963c8a98a390fce175d5d4b5e2.png

 

Só me falta agora implementar a quebra de arquivos para fechar esse exercício.

 

Espero ter explicado.

 

Fui.

gerador de combinacao e permutacao (com opcoes).jpg

gerador de combinacao e permutacao (com opcoes).zip

Link para o comentário
Compartilhar em outros sites

50 minutos atrás, Emumaniaco disse:

Na verdade é um exercício de Análise Combinatória - AC. Mas estava tentando gerar uma calculadora de análise combinatória que vi em visual basic para ser usada no excel (segue arquivo abaixo). Tentei uma aproximação diferente para poder retirar o "lixo" (combinações indesejadas) e me deparei com o seguinte problema: Se você fizer a AC de um número muito grande (milhões de combinações), o excel não vai suportar. Por isso pensei em fazer essa "Calculadora de AC" utilizando colunas dentro de uma matriz com a linguagem de programação que comecei a aprender. Assim poderia fazer a AC não só de números, mas de qualquer coisa que quisesse ('char', 'int' ou 'string' como é o caso).

 

A opção que achei foi separar os resultados em vários arquivos csv ou txt. Tentei fazer com vetores bidimensionais, mas toda vez que compilava, entrava em loop infinito (ainda estou apanhando do parâmetro 'for'). Por isso parti para string.

 

 

O que vai ter nos arquivos? Para que precisa dos arquivos se as permutações podem ser geradas a qualquer momento? Ainda não entendo. Você fala de uma calculadora, mas está calculando o que? Apenas gera as permutações possíveis entre os elementos de cada conjunto?

 

A planilha gera combinações com um elemento de cada conjunto, mas o programa gera as combinações com as strings que por sua vez tem 10 conjuntos de 5 números. Qual é o resultado esperado? O que é uma combinação indesejada?

 

Em C++ se pode separar em cada conjunto os valores fixos, os valores indesejados e os valores opcionais, se é isso que quer fazer, em cada conjunto. Veja seu primeiro vetor

 

std::string vetor00a10[10] =
 {
  "1,2,3,6,7",
  "1,2,3,6,8", 
  "1,2,3,6,9",
  "1,2,3,6,10",
  "1,2,3,7,8",
  "1,2,3,7,9", 
  "1,2,3,7,10", 
  "1,2,3,8,9", 
  "1,2,3,8,10",
  "1,2,3,9,10"
};

 

Isso quer dizer que 1 2 e 3 são fixos, 4 e 5 condenados e 6..10 são combinados em grupos de 2, mas não todos? Qual a lógica de formação?

 

Escreveu praticamente um programa em C, mas que compila em C++.

 

Mas em C++ tem conjuntos --- set --- e pode usar conjuntos de int, set<int> para representar isso. E depois pode usar next_permutation() (no manual) para ir gerando as permutações. E como vem uma a uma pode ir gravando em paralelo em arquivos se de fato precisa deles, ou criar um gerador que retorna a próxima permutação a cada chamada, sem gravar nada...

 

Mas é preciso entender a regra de formação dos conjuntos e das combinações, o que eu não consegui :( 

 

 

Link para o comentário
Compartilhar em outros sites

Citação

O que vai ter nos arquivos? Para que precisa dos arquivos se as permutações podem ser geradas a qualquer momento? Ainda não entendo.

Se você compilar o primeiro código, com os dados que listados, será gerado um arquivo (combinacao.csv) com 100.000 linhas. Eu estou tentando implementar no código uma forma de quebrar esse arquivo em pedaços de 25000 linhas (combinacao1.csv, combinacao2.csv, ..., combinacao4.csv). Coisa que estou batendo a cabeça para entender, encontrar e adaptar ao meu código por causa do meu nível de conhecimento (quase nulo) na linguagem.

 

Citação

Você fala de uma calculadora, mas está calculando o que? Apenas gera as permutações possíveis entre os elementos de cada conjunto?

Erro meu. Na verdade o termo seria gerador de permutações.

 

Citação

A planilha gera combinações com um elemento de cada conjunto, mas o programa gera as combinações com as strings que por sua vez tem 10 conjuntos de 5 números. Qual é o resultado esperado? O que é uma combinação indesejada?

O exemplo que usei foi de um modelo antigo que estava usando para gerar números para loteria. A string pode ser qualquer coisa. Pessoas, cidades, países, etc. Nesse caso específico, seria um arquivo com as permutações viáveis para um jogo de loteria de 00 a 50 números.

 

Citação

Em C++ se pode separar em cada conjunto os valores fixos, os valores indesejados e os valores opcionais, se é isso que quer fazer, em cada conjunto. Veja seu primeiro vetor

...

Isso quer dizer que 1 2 e 3 são fixos, 4 e 5 condenados e 6..10 são combinados em grupos de 2, mas não todos? Qual a lógica de formação?

Como falei acima, é um conjunto viável (pelo meu ponto de vista) de permutações para um jogo de loteria de 00 a 50 números.

Link para o comentário
Compartilhar em outros sites

Em 23/11/2021 às 16:10, Emumaniaco disse:

O exemplo que usei foi de um modelo antigo que estava usando para gerar números para loteria. A string pode ser qualquer coisa. Pessoas, cidades, países, etc. Nesse caso específico, seria um arquivo com as permutações viáveis para um jogo de loteria de 00 a 50 números

 

Como deve ter visto no manual extra-oficial, no link que te mandei, C++ inclui algoritmos para calcular essas coisas.

 

Em 23/11/2021 às 16:10, Emumaniaco disse:

Como falei acima, é um conjunto viável (pelo meu ponto de vista) de permutações para um jogo de loteria de 00 a 50 números

 

Dúvida (minha) 1:
 

Ainda não entendo porque precisa dos dados em arquivos porque seu programa trabalha apenas com constantes e qualquer um dos resultados pode ser gerado na hora usando matemática, os índices.

 

Seu programa original não é assim um programa em C++. Mas compila.

 

A planilha que mostrou é um exemplo de permutação, que pode gerar em uma linha em C++.

 

Dúvida (minha) 2:

 

Não consegui ainda entender a regra de formação dos valores para as tais strings, nem a razão de ter usado strings com 5 números ao invés dos números em si

 

EXEMPLO

 

Vou te mostrar uma maneira de fazer isso em C++, em etapas. Assim poderá testar em sua máquina e talvez ver algumas diferenças na maneira de criar uma solução, ou ao menos minha maneira de tentar isso para ter algo para comparar.

 

Escrevendo em torno dos dados

 

Como sempre escrevo isso, nada de novo: antes de sair programando vou considerar um modelo para os dados.

 

Do seu programa original

 

    std::string vetor00a10[10] =
    {
        "1,2,3,6,7",
        "1,2,3,6,8",
        "1,2,3,6,9",
        "1,2,3,6,10",
        "1,2,3,7,8",
        "1,2,3,7,9",
        "1,2,3,7,10",
        "1,2,3,8,9",
        "1,2,3,8,10",
        "1,2,3,9,10"
    };

 

Isso se repete para as outras dezenas e são apenas constantes. Claro que uma string não é uma constante em C++, é uma classe e pode aumentar ou diminuir de amanho. E cada vetor tem 5 números DENTRO da string. 

Não é nada flexível. E ruim de digitar e conferir.

 

De todo modo os 5 vetores são iguais e apenas na hora de digitar as dezenas são mantidas no código dentro dos limites, mas para o programa nada impede que se digite 
 

    vetor00a10[1] = "Forum Clube do Hardware";

 

logo em seguida, e mudar a segunda string da série. Não há qualquer garantia. E é pouco para um computador.

 

Um outro modelo

 

Para esse exemplo vamos considerar

  • um vetor de inteiros, pequenos, tipo char, para números entre -128 e 127. Vou usar int8_t na declaração, que é o tipo em C e C++ para um int de um byte só. Estão no header cstdint em C++. Mas podiam ser int ou estruturas complexas ou ponteiros para qualquer coisa. É C++ afinal. Amostra será o tipo:
     
        using Amostra = vector<uint8_t>;

     

  • uma Regra, que será outro vetor. Nesse vetor cada elemento vale -1,0 ou 1
    • -1 indica que o número correspondente é excluído do sorteio, como 4 e 5 no seu exemplo
    • 0 indica que o elemento correspondente do vetor de palpites irá para o sorteio das combinações, como 6,7,8,9 e 10 no seu exemplo
    • 1 indica que o número correspondente estará presente em todas as combinações, como 1,2 e 3 no seu exemplo
       
  • Um peso, que será um valor a ser acrescentado a cada número da série resultante. Assim pode usar o mesmo cálculo para todas as dezenas

Porque? 

 

É só um exemplo e só importa que entenda o que se espera antes de começar a programar. Vamos usar vetores de inteiros e controlar as permutações usando duas estruturas em C++: a regra e o vetor

 

Exemplo de regra e vetor

 

     Valores  iniciais:  { 1  2  3  4  5  6  7  8  9 10 }
     Regra (10) numeros: { 1  1  1 -1 -1  0  0  0  0  0 }

 

Essa regra descreve o seu exemplo: 1 2 e 3 fixos, 4 e 5 excluídos e o resto sorteável . Com o valor certo do peso pode criar o vetor da aposta de 25 números. Claro que o programa vai gerar as 120 combinações possíveis nesse caso e não apenas as 10 do seu exemplo. É trivial escolher 10 aleatoriamente entre as 120 se for preciso.

 

Transportando isso para o caso de 5 dezenas vai ter uns milhões de combinações, mas assim é a matemática e a loteria :) . Basta usar a matemática para trazer o total de combinações para algum valor previamente estabelecido.

 

Um exemplo com 24 combinações

 

Mudando para apenas 4 dígitos livres e 3 excluídos as combinações caem para 24 e dá pra ver na tela e conferir. Mudar a regra é simples: troca o 0 por -1 para o 10 por exemplo:

 

     Valores  iniciais:  { 1  2  3  4  5  6  7  8  9 10 }
     Regra (10) numeros: { 1  1  1 -1 -1  0  0  0  0 -1 }

 

A saída para esse caso, usando peso = 40 deve ser

 

        Peso = 40, 10 numeros, 4 no sorteio, 3 fixos, 3 excluidos
        numeros: { 46 47 48 49 41 42 43 44 45 50 }

        As permutacoes:

     1 {   46   47   48   49   41   42   43  }
     2 {   46   47   49   48   41   42   43  }
     3 {   46   48   47   49   41   42   43  }
     4 {   46   48   49   47   41   42   43  }
     5 {   46   49   47   48   41   42   43  }
     6 {   46   49   48   47   41   42   43  }
     7 {   47   46   48   49   41   42   43  }
     8 {   47   46   49   48   41   42   43  }
     9 {   47   48   46   49   41   42   43  }
    10 {   47   48   49   46   41   42   43  }
    11 {   47   49   46   48   41   42   43  }
    12 {   47   49   48   46   41   42   43  }
    13 {   48   46   47   49   41   42   43  }
    14 {   48   46   49   47   41   42   43  }
    15 {   48   47   46   49   41   42   43  }
    16 {   48   47   49   46   41   42   43  }
    17 {   48   49   46   47   41   42   43  }
    18 {   48   49   47   46   41   42   43  }
    19 {   49   46   47   48   41   42   43  }
    20 {   49   46   48   47   41   42   43  }
    21 {   49   47   46   48   41   42   43  }
    22 {   49   47   48   46   41   42   43  }
    23 {   49   48   46   47   41   42   43  }
    24 {   49   48   47   46   41   42   43  }

 

Como na planilha que mostrou.

 

No programa a gente quer escrever algo legível e modificável, como
 

    Regra     regra_teste({ 1, 1, 1,-1,-1, 0, 0, 0, 0, -1});
    Amostra   numeros =   { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int8_t    peso    = 40;  // soma a cada numero do grupo

 

e ter o resultado como acima, para gerar os arquivos ou qualquer uso.

 

E o processo?

 

Se a estrutura que descreve o sorteio fosse Sorteio10 não seria bom poder escrever o simples, para esse exemplo:

 

    Sorteio10 simples = Sorteio10(numeros, regra_teste, peso);

 

O programa que gera isso segue o esperado:

 

#include <iomanip>
#include <iostream>
#include "Sorteio10.h"

int main()
{   // -1 excluido 0 sorteio 1 fixo
    Regra     regra_teste({ 1, 1, 1,-1,-1, 0, 0, 0, 0, -1});
    Amostra   numeros =   { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int8_t    peso    = 40;  // soma a cada numero do grupo
    Sorteio10 simples = Sorteio10(numeros, regra_teste, peso);
    simples.mostra_serie(); // e as permutacoes
    return 0; // nada mais
}

 

Só tem duas funções no programa:

  • mostra_serie()
  • prox_serie()

E dá pra imaginar o que elas fazem:

 

mostra_serie()

 

void Sorteio10::mostra_serie()
{
    std::cout << *this;  // mostra o resumo
    int t = 0;
    while (prox_serie())
    {
        cout << "  " << setw(4) << ++t << " { ";
        for (auto&& n : o_sorteio)
            cout << setw(4) << (int)n << " ";
        cout << " }\n";
    };
}

 

mostra essa parte

 

   Valores  iniciais:  { 1  2  3  4  5  6  7  8  9 10 }
        Regra (10) numeros: { 0  0  0  0  1  1  1 -1 -1 -1 }


        Peso = 40, 10 numeros, 4 no sorteio, 3 fixos, 3 excluidos
        numeros: { 46 47 48 49 41 42 43 44 45 50 }

        As permutacoes:

     1 {   46   47   48   49   41   42   43  }
     2 {   46   47   49   48   41   42   43  }
     3 {   46   48   47   49   41   42   43  }
     4 {   46   48   49   47   41   42   43  }
     5 {   46   49   47   48   41   42   43  }
     6 {   46   49   48   47   41   42   43  }
     7 {   47   46   48   49   41   42   43  }
     8 {   47   46   49   48   41   42   43  }
     9 {   47   48   46   49   41   42   43  }
    10 {   47   48   49   46   41   42   43  }
    11 {   47   49   46   48   41   42   43  }
    12 {   47   49   48   46   41   42   43  }
    13 {   48   46   47   49   41   42   43  }
    14 {   48   46   49   47   41   42   43  }
    15 {   48   47   46   49   41   42   43  }
    16 {   48   47   49   46   41   42   43  }
    17 {   48   49   46   47   41   42   43  }
    18 {   48   49   47   46   41   42   43  }
    19 {   49   46   47   48   41   42   43  }
    20 {   49   46   48   47   41   42   43  }
    21 {   49   47   46   48   41   42   43  }
    22 {   49   47   48   46   41   42   43  }
    23 {   49   48   46   47   41   42   43  }
    24 {   49   48   47   46   41   42   43  }

 

e prox_serie() calcula as combinações
 

bool Sorteio10::prox_serie()
{
    if (inicio)
    {   inicio = false;
        return true;
    }
    return next_permutation(
        o_sorteio.begin(),
        o_sorteio.begin() + possiveis);
}

 

Não vou discutir o programa agora. Ele pode ser visto em https://github.com/ARFNeto-CH/chp21-1121-loto e tem um botão para download. São 4 arquivos pequenos. Escrevi assim porque é o normal e não tenho tempo de ficar juntando essas coisas agora.

 

Outra hora acrescento o lance de gravar as combinações em arquivos. Não é complicado.

 

Sugiro rodar em sua máquina e tentar entender o mecanismo. Pode perguntar qualquer coisa. Não testei quase nada, mas acho que está certo. 

 

Deixo o programa porque vi que é difícil ter esse tipo de exemplo.

 

 

Link para o comentário
Compartilhar em outros sites

Estive pensando em como seria escrever um programa exatamente para fazer isso em C++, 

 

Criação de multiplos arquivos em c++

 

Que afinal é o título da pergunta. E escrevi um programinha de teste. Vou postar aqui porque afinal era a pergunta e assim fica um exemplo completo

 

O Exemplo

 

A ideia é criar algo que recebe e distribui registros entre N arquivos, um por vez. No caso do exemplo são apostas para um tipo de loteria, mas a solução serve para qualquer coisa.

 

main() e o mecanismo

 

#include <iostream>
#include <string>
#include "Desvio.h"
int main(void)
{
    string prefixo{"Arquivo"};
    short  N{12};
    Desvio caminhos(N, prefixo);
    // deve gerar 12 arquivos com 12 linhas
    for (int i = 0; i < 144; i += 1)
    {   string linha = to_string(i);
        caminhos.escolha(linha);
    }
}

 

E é só isso: serão criados N arquivos com o prefixo "Arquivo". Entre os caminhos a cada vez que chamar "escolha()" a linha será gravada no próximo dos N arquivos:
 

image.png.170a683723994be96b1746547cdfdcd3.png

Como cada linha é um número o efeito é que o arquivo 6 por exemplo só vai a lista dos múltiplos de 6 até 144.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Arquivo-6.txt
6
18
30
42
54
66
78
90
102
114
126
138

 

Para ficar mais fácil de conferir o exemplo coloca o nome do arquivo na primeira linha.

 

No caso do seu exemplo seriam 100 arquivos com 1.000 registros cada. Mas não faz diferença e é muito rápido

 

A struct Desvio

 

Ok, a nomenclatura é pobre :( mas Desvio escolhe o caminho e vai...

#pragma once
#include "Caminho.h"
struct Desvio
{
    unsigned short next; // o proximo arquivo
    string         prefix; // prefixo do nome
    unsigned short n;  // quantos arquivos?
    Caminho**      D; // os arquivos

    Desvio(short n_arquivos, string& prefixo);
    ~Desvio(); // apaga tudo
    // manda a linha para o proximo arquivo
    void escolha(string& linha);
};

 

Só tem um método, escolha(), que faz o que se imagina. Na construção da strut os arquivos são criados.

 

Eis a implementação de Desvio

 

#pragma once
#include "Desvio.h"

Desvio::Desvio(short quantos, string& prefixo)
    : n(quantos),
    next(0),
    D(nullptr),
    prefix(prefixo)
{
    // n arquivos de nome prefix-n.txt
    // serao criados, e cada linha da entrada
    // sera gravada nesses arquivos, uma a uma
    //  como cartas do baralho
    if (quantos <= 0) n = 10;
    D = new Caminho* [n] {};
    for (int i = 0; i < n; i += 1)
    {
        string nome = prefix + "-" +
            to_string(i) + ".txt";
        D[i] = new Caminho(nome.c_str());
        D[i]->siga(nome);
    }
}

Desvio::~Desvio()
{    delete[] D;}

void Desvio::escolha(string& linha)
{
    D[next]->siga(linha);
    next = (next + 1) % n;
}

 

;) pobre, mas em Desvio escolha() acha o caminho e chama siga() :D 

 

E Caminho?

 

#pragma once
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
// ninguem merece digitar isso tudo:
using oits = std::ostream_iterator<std::string>;

struct Caminho
{
    ofstream F; // o arquivo
    oits*    it; // o iterador
    string   arquivo;
    Caminho(string arq) : arquivo(arq)
    {
        F.open(arq);
        if ( not F.is_open())
        {
            cerr << "Erro tentando abrir \"" << arquivo
                 << "\". Abortando!\n";
            std::terminate();
        }
        it = new oits{F, "\n"}; // cria o iterador
    };

    ~Caminho()
    { 
        F.close(); // o simples: fecha o arquivo
        delete it; // apaga o iterador
    }
    // grava a linha no arquivo
    void siga(string& linha){ *(*it) = linha; };
};

 

 

Essa só tem o header mesmo porque só tem 30 linhas.

 

A lógica? Caminho não sabe dos desvios. Só da escolha. Então siga() só tem uma linha e grava a string, que vai para o arquivo certinho porque ela só conhece um afinal.

 

Espero que entenda, @Emumaniaco

 

Basta inserir uma linha onde grava o jogo no arquivo e isso acima vai cuidar de gravar em tantos arquivos quanto precise.

 


 

Link para o comentário
Compartilhar em outros sites

  • 3 semanas depois...

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!