-
Posts
6.526 -
Cadastrado em
-
Última visita
Tipo de conteúdo
Artigos
Selos
Livros
Cursos
Análises
Fórum
Tudo que arfneto postou
-
Você ao menos tenteou ler o que está lá nos posts? Eu postei um exemplo, como eu disse, que faz isso de 3 maneiras diferentes, eu acho. E expliquei como funciona. Você leu? #include <algorithm> #include <fstream> #include <iostream> #include <iterator> #include <math.h> #include <string> using namespace std; using ists = istream_iterator<string>; using osts = ostream_iterator<string>; struct filtro { osts saida; filtro(osts s) : saida(s){}; void operator()(string string_x) { const double PI = 3.1415926536; double y = stod(string_x, NULL); double x = y * PI / 180.; x = x * sin(x) * cos(x); *saida = to_string(x); }; }; // filtro() double f(string); // a propria f(x) = x*sin(x)*cos(x) void fase1(string,string); void fase2(); void fase3(string, string); void fase4(string, string); int main(int argc, char** argv) { fase1("entrada.txt","saida1.txt"); fase2(); fase3("entrada.txt", "saida2.txt"); fase4("entrada.txt", "saida3.txt"); return 0; }; void fase1(string arquivo_entrada, string arquivo_saida) { ifstream entrada{ arquivo_entrada }; ofstream saida{ arquivo_saida }; ists x{ entrada }; ists fim{}; osts fx{ saida, "\n" }; copy(x, fim, fx); }; void fase2() { const string valores[8]{ "0","30","45","90", "-30","-45","-90","90" }; for (auto& x : valores) { cout << "Angulo: " << x << " graus.\tf(x) = " << fixed << f(x) << endl; }; } void fase3(string arquivo_entrada, string arquivo_saida) { ifstream entrada{ arquivo_entrada }; ofstream saida{ arquivo_saida }; ists x{ entrada }; ists fim{}; osts fx{ saida, "\n" }; filtro f(fx); for_each(x, fim, f); }; void fase4(string arquivo_entrada, string arquivo_saida) { ifstream entrada{ arquivo_entrada }; ofstream saida{ arquivo_saida }; string x; entrada >> x; while (!entrada.eof()) { saida << to_string(f(x)) << endl; entrada >> x; }; // while() entrada.close(); saida.close(); }; double f(string string_x) { const double PI = 3.1415926536; double x = stod(string_x, NULL); x = x * PI / 180.; return (x * sin(x) * cos(x)); }; // f() // fim Não leu isso lá? Talvez eu não devesse ter deixado com o botãozinho de conteúdo oculto. É que o post era grande e nem todo mundo lê. E menos ainda lê o código.
-
pode usar um typedef Tente algo assim typedef BOOL (_stdcall *SystemSetConsoleCursorPosition) (HANDLE, COORD); SystemSetConsoleCursorPosition MinhaSystemSetConsoleCursorPosition = SetConsoleCursorPosition; E aí poderá chamar MinhaSystemSetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), (COORD){ 0,0 }); Ou estava falando sério?
-
como eu te disse, optei por não usar colisão elástica e usei um desvio das partículas porque eu só queria ver o efeito. E colisão elástica nem existe afinal Deixei a atribuições aleatórias mas separei a carga em primeira_nuvem() porque acho muito mais legal programar as nuvens de partículas não aleatórias, tipo em pares de partículas em rota de colisão, ou convergindo em grupo. É mais colorido. Ou algo como o game life, onde as partículas ao colidir podem desaparecer ou se multiplicarem. Experimente. Usando as estruturas como te mostrei fica bem mais fácil de controlar e de ler. Uma configuração, Nuvem, Particula e Tela. Teve oportunidade de ler o código que eu postei? E as colisões em impacto() são tratadas internamente porque a função recebe o endereço da Nuvem e as partículas a verificar: int impacto( const uint16_t a, const uint16_t b, const Nuvem* N, const Config* cfg) { e a rotina devolve a Nuvem atualizada. Bem mais simples. Não faz diferença se vai calcular vfinal() usando colisão elástica ou extinguir uma das partículas ou explodir em um grupo mantendo a massa pra simular uma explosão Só altera em um ponto. E estamos em C então pode mudar o protótipo de impacto() e acrescentar o endereço de uma função de cálculo, embora eu ache que mudar isso durante uma simulação pode ter um efeito ruim na eventual transição de uma função para outra durante uma simulação Note que as colisões podem ser revistas usando um algoritmo como o bubble sort, e no lugar daquela "otimização" 1d10t@ que sai quando não faz nenhuma troca no loop --- o tal algoritmo otimizado, tipo não-***** --- você sai quando não tem nenhuma colisão no loop. É o mesmo algoritmo e acho que foi assim que eu escrevi no exemplo. Pode usar o próprio valor avaliado na colisão e recuar as partículas para o momento imediatamente anterior à colisão, e aí deixar o algoritmo aplicar o desvio calculado com as velocidades corrigidas. Bem simples. Mas acho mesmo mais intuitivo e simples para calcular usar velocidade linear e ângulo ao invés de vx e vy.
-
void Limpa_a_Metade_da_Tela(){ int i; MoveToXY(0,9); for(i=0; i<1120; i++) printf(" "); } MoveToXY() é legal. Afinal linha e coluna! Limpar metade da tela? Como sabe o tamanho? Identifique antes o tamanho da tela. Veja a documentação no local de sempre BOOL WINAPI GetConsoleScreenBufferInfo( _In_ HANDLE hConsoleOutput, _Out_ PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo ); Acho que já postei exemplos aqui Se usar o "novo" pós-2018 modelo de programação para a console acho que tem comandos clr_eol clr_eos clr_bol e clear_screen mas eu nunca usei. Esses são previstos para limpar a tela da posição do cursor até o início da linha, até o fim da linha e até o fim da tela. Ou a tela toda, claro Mas 1120 chamadas a printf() pode não ser assim eficiente mesmo em computadores modernos Ampliando um pouco sua pesquisa pode ver que gotoxy() era parte de uma biblioteca conio.h fornecida com o compilador TurboC da Borland, hoje Embarcadero, no fim dos anos 80. E tem se mantido viva até hoje. Uma versão mantida desde 2005 em sourceforge.net pode ser baixada hoje ainda em https://sourceforge.net/projects/conio/ Eis o header para quem quer viajar no tempo Não sei qual a origem dessa conio.h nos exemplos de @devair1010 e talvez ela não inclua essa função e por isso essa e algumas outras apareçam reescritas várias vezes, como textcolor() que também deveria estar lá
-
while(1){ if(GetAsyncKeyState(VK_UP)){ y--; if(y < 0){ y = 2; } gotoxy(11, y); Sleep(200); } else if(GetAsyncKeyState(VK_DOWN)){ y++; if(y > 2){ y = 0; } gotoxy(11, y); Sleep(200); } } Sobre esse loop e versões modernas de Windows, direto da documentação: GetAsyncKeyState() nem sempre funciona e por isso menus que contam com isso às vezes parecem "enroscar" em computadores modernos se o cara fica apertando uma das setas seguidamente. A causa está descrita no manual: Essa função retorna DUAS coisas. Em geral os programas testam --- como esse trecho --- como se ela retornasse verdadeiro ou falso. Só que ela retorna SHORT SHORT GetAsyncKeyState( int vKey ); ou WORD ou algo com 16 bits. uint16_t é um tipo portável hoje em dia. A função retorna dois bits: o mais significativo indica se a tecla está apertada no momento da chamada. E funciona. No popular é o bit de sinal: se retornar negativo, que é falso, quer dizer que a tecla está apertada no momento da chamada o menos significativo indica se ligado que a tecla foi pressionada desde a chamada anterior a GetAsyncKeyState(). Ou seja, ela pode não estar apertada entre essa chamada e a anterior a essa função. Se houve alguma, claro Só que nas versões 32 ou 64 bits de Windows, dos últimos 30 anos, outra aplicação pode ter recebido essa mensagem e o seu menu nunca vai receber. E como a tecla não está mais pressionada os dois bits estão desligados e a função vai retornar zero: em resumo: você perdeu a tecla Citando a documentação oficial: gotoxy() - já postei isso aqui um certo número de vezes, e vamos somar 1 ao contador: se essa função é sempre incluída nos programas que eu vejo e compilada de novo e de novo, como aqui: void gotoxy(int x, int y) { HANDLE hCon; COORD dwPos; dwPos.X = x; dwPos.Y = y; hCon = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hCon,dwPos); } Porque não escrever o esperado para programadores e leitores sem formação matemática, esses que não pensam em plano cartesiano ao ler (x,y) como coordenadas, e escrever void gotoyx(int linha, int coluna) { COORD dwPos; dwPos.X = coluna; dwPos.Y = linha; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),dwPos); } usando linha e coluna como sempre? O geral é menu() ser uma função que retorna um valor, possivelmente um valor pequeno afinal é um menu. Ao menos no início do programa o menu costuma vir do disco porque é muito mais fácil editar o texto num arquivo txt no IDE do que ficar lutando com aquela cascata de printf() e aspas e '\n' e o d1@b0 Então a função lê as opções, põe na tela uma depois da outra, seleciona a opção padrão e fica num loop, como mostrado acima pelo @Lucca Rodrigues . No loop ela aceita apenas as setas, em geral ESC para cancelar e ENTER para selecionar. Nada mais. No retorno de menu() um loop testa o valor retornado, em geral em algo como um comando switch(), e a vida segue. Lembro que não existe um comando switch/case. Trata-se de fake news o comando é switch e o case é o prefixo de um label.
-
O simples: stod() converte de string para float double stod (const string& str, size_t* idx = 0); double stod (const wstring& str, size_t* idx = 0); Postei um exemplo completo aqui nesses dias: E há outros exemplos lá. E alguns posts mais ou menos úteis
-
É como temos desde o ensino médio afinal. Por isso acho que usar coordenadas polares e um espaço linear para os pixels facilitaria as contas todas. E é mais intuitivo para pensar no modelo porque as partículas se movimentam em módulo, direção e sentido. Uma direção. E decompor a cada momento a direção em deslocamento x e deslocamento y é chato. Usei porque era o que o tópico citava, mas eu nunca tinha visto e então não andei quase nada. Meu programa não deve servir como exemplo do uso da API Mas é divertido de ficar olhando. Eu ia postar mas como estava já resolvido deixei pra lá. Mas ontem eu lembrei disso de novo Se tiver alguma ideia e quiser alterar pode propor lá direto e eu incorporo. Lá tem um botão de download também. Deixei em um arquivo ou dois porque eu ia postar no forum. Eu não tenho esse ambiente para programar porque eu nem conhecia. E não tenho assim muito interesse para instalar e compilar pacotes grandes de coisas que não uso e nem conheço. Só que eu uso vcpkg no meu ambiente Windows e allegro foi portada para vcpkg então eu instalei. É outra versão mas também aí seria pedir muito ter a versão certinha. Mas vcpkg install allegro5 E estava ok minutos depois. E tinha um link para um manual de referência em PDF e o seu programa então... O programa está aqui. Basicamente o que eu mudei foi a estrutura para ficar mais controlável: o programa roda em torno dessa configuração typedef struct { uint16_t altura; uint16_t largura; double min_velocidade; uint16_t n_Part; unsigned semente; double time_out; const char* titulo; ALLEGRO_COLOR fundo; ALLEGRO_DISPLAY* display; ALLEGRO_EVENT_QUEUE* eventos; ALLEGRO_KEYBOARD_STATE teclado; ALLEGRO_TIMEOUT timeout; } Config; Mais flexível para eu alterar. Eu reprogramei a parte de saída pra sair com ESCAPE ou clicando no X para fechar a janela. E usei uma Nuvem para as partículas typedef struct { float x; float y; float raio; float massa; float vx; float vy; ALLEGRO_COLOR cor; } Particula; typedef struct { uint16_t nPart; // contagem Particula** p; // as próprias } Nuvem; E uma Tela pra por a Nuvem. Assim é mais flexível e dá pra ter mais telas e nuvens no mesmo programa. Achei que ia ficar mas colorido e festivo typedef struct { ALLEGRO_BITMAP* buffer; uint16_t H; // altura em pixels Nuvem* nuvem; uint16_t W; // largura } Tela; A lógica eu acho que não mudei. Apenas dividi em primeira_nuvem() e proxima_nuvem() com o sentido óbvio.
-
Sei que resolveu isso, mas fiquei curioso em ver como seria isso rodando por uns minutos e escrevi uma parte. Não conheço esse então não fui nada longe Mas fiquei pensando nessas coisas então vou comentar aqui não seria melhor (mais fácil de programar e controlar) usar coordenadas polares e uma estrutura linear? Eu copiei seu código para começar, mas não sei s e faria de novo assim eu escrevi uma estrutura Nuvem para por as partículas e uma Config para controlar a geração e aí usei duas funções: primeira_nuvem() e proxima_nuvem() para controlar o sistema acabei achando que é mais divertido criar as partículas on-purpose do que aleatoriamente também. É mais divertido apontar umas para as outras desisti das colisões elásticas. Achei mais interessante quando tem uma colisão parar a menor e criar uma nova partícula descendente da maior e desviar uma para cada lado por um certo ângulo mas separei o tratamento da colisão numa rotina impacto() separada Veja uma primeira_nuvem() Nuvem* primeira_nuvem(Config* cfg) { Nuvem* const nv = (Nuvem*)malloc(sizeof(Nuvem)); nv->p = (Particula**)malloc(cfg->n_Part * sizeof(Particula*)); // primeira nv->p[0] = gera_particula(cfg); nv->nPart = 1; // as outras while (nv->nPart < cfg->n_Part) { // cria um vetor de particulas, a nuvem // coloca a nova na proxima posicao livre nv->p[nv->nPart] = gera_particula(cfg); nv->nPart += 1; // conta a nova while (colide_com_nuvem(nv->nPart - 1, nv) >= 0) { // enquanto colidir tenta outra posicao nv->p[nv->nPart]->x = nv->p[nv->nPart]->raio + (rand() % cfg->largura - nv->p[nv->nPart]->raio); nv->p[nv->nPart]->y = nv->p[nv->nPart]->raio + (rand() % cfg->altura - nv->p[nv->nPart]->raio); }; // while() // ok: sem colisao }; // while() return nv; }; // primeira_nuvem() Esse foi o jeito que arrumei para a geração inicial. E cada próxima geração algo assim Tela* proxima_nuvem(const Tela* prev, const Config* cfg) { char n_colisoes = 0; do { // move uma particula pA for (int a = 0; a < prev->nuvem->nPart; a += 1) { Particula* pA = prev->nuvem->p[a]; if ((pA->vx == 0) && (pA->vy == 0)) continue; for (int b = a + 1; b < prev->nuvem->nPart; b += 1) { Particula* pB = prev->nuvem->p[b]; // a outra n_colisoes = impacto(a, b, prev->nuvem, cfg); }; // for() pA->x += pA->vx; pA->y += pA->vy; // pA andou // se esta nas bordas inverte o sentido if ((pA->x >= prev->W - pA->raio) || (pA->x <= pA->raio)) pA->vx *= -1; if ((pA->y >= prev->H - pA->raio) || (pA->y <= pA->raio)) pA->vy *= -1; if (n_colisoes > 0) break; }; // for() } while (n_colisoes != 0); return (Tela*)prev; // retorna a nova Tela }; // proxima_nuvem() impacto() devolve a Nuvem corrigida se a bateu em b e assim é mais fácil alterar "políticas de colisão" Mas vou parar porque é como um game e gasta muito tempo. Veja um movimento de uma nuvem de 40 delas E depois de uns 30s
-
Em geral não faz muito sentido usar isso. Talvez se a entrada padrão estiver redirecionada para um arquivo algo como type x.txt | programa.exe para ler de x.txt ao invés do teclado em Windows. Recomento evitar. Se quer ler até o '\n' faça isso explicitamente. fseek() em stdin não faz sentido, como não faz fflush().
-
C nao estou conseguindo fazer esse programa
arfneto respondeu ao tópico de souza souza00 em C/C#/C++
até onde eu sei o forum é exatamente para isso, se o "isso" de que fala for ajuda e não um programa pronto Você tem um livro? Recomendo muito que adote um livro se seu curso não tem um. Atende para a descrição do comando no tópico #3 acima. É praticamente seu programa todo. -
C++ Criar janela e botão continuar/codeblocks
arfneto respondeu ao tópico de Ejji_Stotch em C/C#/C++
Não, não está. Está criando um rpg em C++. E está usando o Code::Blocks para criar o programa em C++. É uma distinção importante. Está imaginando que o jogo vá ser usado de dentro de uma janela do ambiente de desenvolvimento e não faz sentido. O seu programa em C++ vai gerar um arquivo executável. E no mundo normal ele seria associado a um ícone e um atalho. E alguém para jogar clica no ícone e a coisa anda. Não deve imaginar que alguém vá compilar seu programa a cada vez que for rodar o jogo. Não é prático. Pois é: você não deve misturar código e texto. Vai ficar impossível de gerenciar e muito chato para programar e corrigir. Não se mistura essas coisas. Veja isso de seu programa: cout<< "\nQuentin: Mas isso é assunto pra quando você melhorar, não há nada\ que você possa fazer a não ser melhorar"<<endl; cout<< "Ginug: Com essa chuva lá fora, não há muito que se possa fazer.."<<endl; cout<< "Quentin: É bom ver que está bem, tenho uns assuntos para re\ solver, nesse caso, Ginug poderia fazer a genileza de chamar Mildga, \ ela vai querer ver "<< nome_personagem << "."<<endl; cout<< "Ginug: Sim, claro, (sarcástico) eu ando muito atarefado\ mesmo, com essa chuva ae fora ainda.."<<endl; cout<< "\nOs dois se despedem, você está sozinho no quarto, isso te\ faz pensar um pouco no ocorrido, tu não sente tristeza ou angústia por não ter\ lembranças, porém sente medo de ter perdido algo importante..."<<endl; cout<< "Um momento se passa, logo após uma mulher de cabelos longos\ e pretos aparece na porta, ela carrega uma bolsa na cintura, em suas botas há barro\ por conta da chuva, ela te encara por um momento."<<endl; cout<< "\nNPC3: Vejo que está melhor, me chamo Mildga, fui eu quem ajudou com os ferimentos, sinceramente não acho que teria sobrevivido caso, (como era mesmo\ o nome dele...)Quentin! isso, caso Quentin não tivesse te encontrado.."<<endl; cout<< "E então posso dar uma olhada? aliás como se chama?"<<endl; cout<< "\nVocê explica o ocorrido a Mildga enquanto\ ela tira suas faixas, tu ainda sente um pouco de dor, olha sua\ barriga (parte inferior direita) e\ percebe três riscos como fosse realmente uma garra que tivesse causado o ferimento"<<endl; cout<< "Mildga faz os curativos necessários e pede pra você repousar."<<endl; cout<< "\nMildga: É uma pena, infelizemnte tudo \ que posso fazer por você é isso, vou enviar um garoto, a saber seu nome é \ Griffin, ele te auxiliará no que for preciso, inclusive a respeito da comida,\ aquele rapaz fez questão"<<endl; cout<< "de deixar tudo pago, Quentin, isso."<<endl; cout<< "\nMomentos mais tarde um garoto aparece..."<<endl; cout<< "\nNPC4: Olá, me chamo Griffin, Mildga me disse pra vir\ e te destrair, ela disse que vai me dar umas moedas depois, mas a verdade\ é que eu queria as moedas ontem, hoje não tem mais suco de groselha..aaahh"<<endl; cout<< "Griffin: Ah! É verdade que uma fera te atacou? como ela\ era? eu nunca vi uma fera antes, mas quando eu crescer eu vou ser\ um grande cavaleiro!"<<endl; Note que em C++ você pode continuar qualquer linha terminando com '\'' e digitando na próxima linha. Isso dentro de strings. Assim evita essas linhas extra longas ruins de ler, em especial numa janela do programa fraquinho do forum. Mas compare com a mesma coisa: #A0128# Quentin: Mas isso é assunto pra quando você melhorar, não há nada que você possa fazer a não ser melhorar Ginug: Com essa chuva lá fora, não há muito que se possa fazer... Quentin: É bom ver que está bem, tenho uns assuntos para resolver, nesse caso, Ginug poderia fazer a gentileza de chamar Mildga, ela vai querer ver "<< nome_personagem >>" Ginug: Sim, claro, (sarcástico) eu ando muito atarefado mesmo, com essa chuva ae fora ainda... Os dois se despedem, você está sozinho no quarto, isso te faz pensar um pouco no ocorrido, tu não sente tristeza ou angústia por não ter lembranças, porém sente medo de ter perdido algo importante... Um momento se passa, logo após uma mulher de cabelos longos e pretos aparece na porta, ela carrega uma bolsa na cintura, em suas botas há barro por conta da chuva, ela te encara por um momento. NPC3: Vejo que está melhor, me chamo Mildga, fui eu quem ajudou com os ferimentos, sinceramente não acho que teria sobrevivido caso, (como era mesmo o nome dele...) Quentin! isso, caso Quentin não tivesse te encontrado... E então posso dar uma olhada? aliás como se chama? Você explica o ocorrido a Mildga enquanto ela tira suas faixas, tu ainda sente um pouco de dor, olha sua barriga (parte inferior direita) e percebe três riscos como fosse realmente uma garra que tivesse causado o ferimento Mildga faz os curativos necessários e pede pra você repousar. Mildga: É uma pena, infelizemente tudo que posso fazer por você é isso, vou enviar um garoto, a saber seu nome é Griffin, ele te auxiliará no que for preciso, inclusive a respeito da comida, aquele rapaz fez questão de deixar tudo pago, Quentin, isso. Momentos mais tarde um garoto aparece... NPC4: Olá, me chamo Griffin, Mildga me disse pra vir e te distrair, ela disse que vai me dar umas moedas depois, mas a verdade é que eu queria as moedas ontem, hoje não tem mais suco de groselha..aaahh Griffin: Ah! É verdade que uma fera te atacou? como ela era? eu nunca vi uma fera antes, mas quando eu crescer eu vou ser um grande cavaleiro! Na prática você separa os diálogos por blocos numerados, que vem da memória ou do banco de dados, e são parte dos dados e que ficam separados do programa. Assim você pode ter todo o texto disponível para formatar, corrigir, usar um corretor ortográfico e tal. E não precisa mudar o programa porque mudou uma frase que estava errada. No programa só tem chamadas a uma classe. Texto por exemplo, onde tem um método int mostra_local(string local); e você chamaria com mostra_local("#0128#"); // por exemplo E a classe trocaria os campos por exemplo "<<valor>>" pelo certo no contexto do jogo. Do modo como está fazendo rapidamente vai ficar impossível de controlar. -
C++ Como tratar dados de um arquivo txt numa função matemática em C/C++???
arfneto respondeu ao tópico de Welington Silva 2002 em C/C#/C++
Que tinha nos vídeos e pesquisas sobre copiar um arquivo? Como está seu programa agora? O programa que você quer escrever é chamado genericamente de filtro: apenas lê a entra e gera uma saída com uma possível transformação, que seria o tal filtro. No seu problema filtro está bem definido e é aquela função.Mas o enunciado não diz se a medida x está em graus ou radianos e essa é uma falha comum. Ou você não disse, e aí seria outra falha comum Imaginando que o valor de x venha em graus, o comum no BR, você precisa converter para radianos antes porque as funções sin() e cos() --- como todas as funções trigonométricas --- operam em radianos e não em graus. E aí tem outra pergunta: o valor de x na função será o valor convertido em radianos ou o valor que está no arquivo? Do ponto de justa de uma função matemática é mais certo considerar o valor de x na função como o valor em radianos Para converter de graus para radianos tem a fórmula do ensino fundamental, certo? Não sei o que quer dizer. Mas porque não usar fluxos mesmo e usar o operador de extração popularmente conhecido por ">>"? Você tem um livro? Tem uma tabela das funções em <string> ? Uma pesquisa minimalista em português com aquele conhecido site de busca mostra é só o que precisa fazer. De volta ao programa a função: o programa é muito simples e escrever uma classe só com essa função seria um exagero então vamos pensar em uma função f que recebe um argumento x que é uma string assim é mais fácil, porque vem do arquivo assim, uma string. Para a saída pode ser double mesmo porque afinal as classes stream tem overloads para double e você pode escrever por exemplo cout << " Valor do double x: " << x; // '<<' converte x para string o protótipo double f(string string_x); já estaria bem porque é só o que temos: vem uma string volta um double exemplo de uma função de teste para f() void fase2() { const string valores[8]{ "0","30","45","90", "-30","-45","-90","90" }; for (auto& x : valores) { cout << "Angulo: " << x << " graus.\tf(x) = " << fixed << f(x) << endl; }; } O simples, certo? pega esses 8 valores conhecidos, em graus, e chama a função. E faz a gentileza de mostrar os valores na tela ou não ia adiantar nada afinal Eis uma saída Angulo: 0 graus. f(x) = 0.000000 Angulo: 30 graus. f(x) = 0.226725 Angulo: 45 graus. f(x) = 0.392699 Angulo: 90 graus. f(x) = -0.000000 Angulo: -30 graus. f(x) = 0.226725 Angulo: -45 graus. f(x) = 0.392699 Angulo: -90 graus. f(x) = -0.000000 Eu repeti os valores aqui porque estão aqui na minha tela e pode ajudar a conferir, mas o simples é abrir o Google Planilhas, grátis, ou o Excel 365 e digitar a fórmula numa planilha e assim pode digitar e conferir qualquer valor, certo? porque fase2()? Se leu o nome da função pode ter ficado curioso. É porque esse era o segundo teste óbvio a fazer. O primeiro seria qual? Ler o arquivo e gerar a saída, claro. Eu preferi escrever antes sobre a função polo lance dos graus. Por falar no filtro, um "programa" para ler da entrada para a saída: Estamos considerando um arquivo que só tem valores de x. Podem estar um por linha um vários numa linha talvez, mas serão apenas valores de x. Em C++ há claro muitas maneiras de ler isso, mas o simples é usar streams e ler com ">>" e gravar com "<<". Porque não? No entanto como é apenas um filtro e estamos usando C++ isso deve estar disponível em vários sabores, cores e tamanhos. Mas apenas com << >> e a função acima já serve, dentro de um loop, para resolver o problema Um exemplo trivial: copiar strings da entrada para a saída. Veja fase1(), um programa de uma linha só: void fase1(string arquivo_entrada, string arquivo_saida) { ifstream entrada{ arquivo_entrada }; ofstream saida{ arquivo_saida }; ists x{ entrada }; ists fim{}; osts fx{ saida, "\n" }; copy(x, fim, fx); }; É só isso: copia do arquivo entrada para o arquivo saida as strings todas. Abre os arquivos, cria a saída, roda o loop, copia as strings e termina. O final vai ser dado por fim, que é o caso de ler {} --- ou seja nada --- do arquivo de entrada. Em C++ os iteradores fazem muito dessas coisas comuns de loop e filtros ficarem triviais. Entenda que as strings vão estar separadas um '\n' na saída: esse é o segundo parâmtetro de fx. Se você quisesse fazer por exemplo um sort() ou separar as palavras únicas ou sei lá o que, basta usar a mesma coisa do lado da entrada. Um iterador de entrada. E faz sentido. Só que copy() não processa. Claro que deve ver alguma maneira de processar e aí seria só copiar o programa de uma linha para outro programa de uma linha. Processar no seu caso é apenas chamar aquela função que calcula f(x). E tem. Pelo menos duas. for_each() e transform() servem Mas e a função como podia ser? Era uma das dúvidas afinal Pode ser algo bem simples assim: double f(string string_x) { const double PI = 3.1415926536; double x = stod(string_x, NULL); x = x * PI / 180.; return (x * sin(x) * cos(x)); }; // fx() Podia ser mais curta mas assim é mais fácil de ler. E como transformar cada x na entrada em f(x) na saída? A opção "moderninha" em C++ é usar uma struct filtro porque afinal é um filtro. Assim se pode usar outras funções e gravar em outros arquivos ou com outros delimitadores por exemplo. Tudo que a gente precisa na struct é a saída e a função, certo? struct filtro { osts saida; filtro(osts s) : saida(s){}; void operator()(string string_x) { const double PI = 3.1415926536; double y = stod(string_x, NULL); double x = y * PI / 180.; x = x * sin(x) * cos(x); *saida = to_string(x); }; }; // filtro() Sim, a função está dentro da struct e o iterador de saída que vai ser usado pra gravar os dados. É só o que precisa ter. using osts = ostream_iterator<string>; Esse using é como um typedef C para não ter que digitar toda hora esse nome gigante. o {} é porque não tem código nenhum a mais: basta fazer saida = s para inicializar a saída e saber onde gravar os dados. E isso está lá mais compacto depois dos ':'. É o jeito comum de construir essas coisas. A struct só tem uma variável: saida. E como fica um programa que usa um filtro desses? void fase3(string arquivo_entrada, string arquivo_saida) { ifstream entrada{ arquivo_entrada }; ofstream saida{ arquivo_saida }; ists x{ entrada }; ists fim{}; osts fx{ saida, "\n" }; filtro f(fx); for_each(x, fim, f); }; Passou de uma para duas linhas. A declaração do filtro e o for_each(). Claro que essa podia ser main() Vou deixar um exemplo no fim e não queria escrever um programa com cada teste... Para chamar seria algo bobinho como : fase3("entrada.txt", "saida2.txt"); e vai criar o arquivo com os resultados. Como funciona? A lógica é simples: vai ler de x até fim. fim é quando não lê nada, tipo EOF ou erro. Vai ler strings. porque ists é using ists = istream_iterator<string>; Porque é muito chato escrever esses nomes grandes e faz o simples parecer complicado. Como ists é um iterador de string a vida segue: ele vai ler todas as strings na entrada até o fim de arquivo e passar cada uma delas para o filtro f. E o filtro f é uma variável, uma struct filtro. E faz sentido, certo? Essa linha filtro f(fx); declara f como sendo aquela struct, e fx é o parâmetro que vai ser usado para a saída. E a conta fecha: era preciso saber só o filtro --- a função de transformação --- e o arquivo de saída. Declaramos os dois. E se for preciso usar outro filtro ou outro arquivo de saída no mesmo programa sem problemas: basta declarar outros. Note que um programa sólido precisaria ter mais alguns cuidados. Isso aqui é um exemplo, escrito na hora do café. Mas acho que dá pra ver porque é mais rápido criar modelos com esse tipo de linguagem. A linha seguinte for_each(x, fim, f); faz o serviço: consome a entrada todinha passando cada string lida para f, o filtro que tem a função dentro. Note que na entrada as strings serão aceitas uma ou mais por linha. Tanto faz entrar com 0 30 45 90 -30 -45 -90 ou 0 30 45 90 -30 -45 -90 Se preciso for exigir uma só string por linha não é nada especial. Escrevi isso assim porque eu escolhi e porque é meu exemplo afinal. Eu queria só mostrar a técnica porque não vejo isso nos exemplos C-like que tem nos livros. Mas e se for pra escrever como em C dos '80? Não é muito mais difícil. Vai passar de duas para 7 linhas void fase4(string arquivo_entrada, string arquivo_saida) { ifstream entrada{ arquivo_entrada }; ofstream saida{ arquivo_saida }; string x; entrada >> x; while (!entrada.eof()) { saida << to_string(f(x)) << endl; entrada >> x; }; // while() entrada.close(); saida.close(); }; Usando os operadores normais de extração e inserção para streams, os tais << e >>, que são na verdade os operadores de shift redefinidos para streams. Coisas de C++ e classes stream. São chamados overload O programa de exemplo com as 4 fases e o teste está aqui Espero que ajude a entender as opções -
C Coisas obsoletas/que deveriam ser evitadas em C
arfneto respondeu ao tópico de Lucca Rodrigues em C/C#/C++
Eu disse que é folclórico porque ncurses é totalmente baseada em terminfo e ioctl() e essas coisas não tem correspondente em Windows. Ou não tinham até 2018 e o CONPTY da Microsoft. E do lado do Windows tem o SUBSYSTEM:CONSOLE e tudo em volta dele, que não tem correspondente no Linux. Por isso acho folclórico implementar toda uma camada de suporte para as funções rodarem no Windows. Usei curses durante muito tempo, em Unix. Sempre tive meus candidatos a portar do Unix pro Windows e até precisei portar algumas coisas, como getopt() em especial, mas nunca pensei em ncurses. Talvez porque nunca escrevi nada usando curses que tivesse valor em usar no Windows. E exceto pela portabilidade eu nunca cheguei a ver razão para usar ncurses e não qualquer outra API ou framework disponível no Windows mesmo. Mas é legal que seja portável. Nesses dias mesmo pensei em usar algo assim para um configurador em uma máquina na nuvem. -
C Coisas obsoletas/que deveriam ser evitadas em C
arfneto respondeu ao tópico de Lucca Rodrigues em C/C#/C++
Talvez eu já tenha te dito isso. Me desculpe se soar repetitivo Em geral não era nem pra ler to teclado mesmo. Interfaces gráficas são mais controláveis e o visual e o resultado compensam. A API do sistema era pra ser o padrão mas o modelo de programação é um p0R$R$3, difícil de escrever, de ler e de manter. Então ninguém usa. Todas as API que já vi e que tiveram ou tem algum sucesso vão no caminho de como era em curses nos '80. Eventos, Initialize(), CallBacks... Como o Delphi dos '90, o Qt, SDL, wxwidgets, GTK, OpenGL, DirectX... De todo modo para o cara que está aprendendo e para programas que podem tolerar alguma falta de controle o melhor é ler as letras com fgetc() ou as linhas com fgets(). E converter os tipos usando as bibliotecas. Muito simples e efetivo. Para o uso profissional e para programas que não podem tolerar uma entrada imprevista ou zoar uma tela bonitinha então o caminho é Em windows: não ler do teclado. Usar PeekConsoleInput() e ler direto do buffer. Desabilitar echo usando SetConsoleMode() e separar a leitura do display: você marca as teclas que aceita e quando vem algo: se for uma delas: você mostra o símbolo na tela, avança o cursor ou faz o que faz sentido no seu programa. Se leu o campo todo você retorna o valor e pronto Se for inválida você usa um Beep() ou mostra uma mensagem de status e continua esperando Em Linux/MacOS você usa ioctl() e muda VTIME e VMIN para zero, desabilita eco e faz a mesma coisa que no Windows, só que como o Linux não tem console você usa read() mesmo. Ou fgetc() ou qualquer coisa. Apenas lê como seria no Windows. Só que o programa não para. O essencial é não parar o programa na leitura. Já tive dificuldade para explicar isso mas imagine um programa/jogo de tiro parar num read() e perguntar: "Tecle ENTER para atirar" "Digite a direção do tiro e tecle 2" -
C O terminador 0 de strings faz parte do seu tamanho?
arfneto respondeu ao tópico de Lucca Rodrigues em C/C#/C++
No fundo nada tem a ver. Uma declaração é algo bem mais genérico. Veja a declaração: char frase[40]; Em geral se deve ler uma declaração da direita para a esquerda. E lá estão os colchetes. Então é um array. Em seguida tem o número: 40. Então são 40 coisas. Como vem o '[' então essa é a contagem definitiva Então aparece o identificador: 'frase': então trata-se de uma sequência linear de 40 coisas e será identifica por esse símbolo. 'frase' Então aparece char, o tipo. E aí a conta fecha. Ou o programa não compila. A conta fecha assim: será alocado um total de 40 vezes o necessário para conter um char, e o endereço inicial será frase. Um char ocupa sizeof(char) e é isso o que será alocado. A questão de usar como uma string, null-terminated como é o caso em C, é secundária. O que tem lá dentro é problema seu, do programa. Você tem acesso a 40 bytes, em geral. Nada mais. Se sua máquina usar char de dois bytes terá 80 bytes. É só isso. Se tentar acessar um byte além disso seu programa deve cancelar por Access Violation, SegFault ou sei lá que nome seu sistema vai dar. E é melhor que cancele mesmo porque estará lendo ou gravando em algo desconhecido e talvez alheio. Em épocas em que as máquinas não tinham sistemas tão sólidos como os de hoje era uma maneira de ler conteúdo de outros programas, ou mesmo de derrubar o sistema como um todo. Me intrometendo em sua pergunta, essa era uma razão para usar fgets(frase,40,stdin); ao invés de scanf(), como sugeriu @Midori scanf() tem problemas ao ser usada para algo para o que não foi escrita. Teclado não é entrada formatada. Voltando ao vetor Seu programa tem essa área para usar e pode fazer o que quiser com ela. Se quer usar como string ela é terminada por nulo. Então se tem 40 pode usar até 39 não nulos. Se precisa dos 40 pode esquecer o nulo e usar outro artifício. Se quer gravar várias strings lá dentro também pode, apenas controle os ponteiros e os terminadores. Em muitos casos se aloca uma área assim, maior, tipo 4K ou 8K e dentro dela se aloca strings menores, tipo buffers de transmissão ou sinais recebidos ou pulsos de áudio, coisas que tem que chegar e serem guardadas rápido sem muita estrutura. Uma "memória interna" do programa. -
C Coisas obsoletas/que deveriam ser evitadas em C
arfneto respondeu ao tópico de Lucca Rodrigues em C/C#/C++
conio.h: Esse era meu primeiro palpite, e era fácil. Eu postei outro dia o que tem nessa biblioteca e não é nada empolgante. E achar uma cópia disso para manter na máquina para usar uma única função cujo propósito é ler uma letrinha é algo pra pensar. E ver ncurses, sucessora de curses, ser proposta como alternativa em muitos lugares também é folclórico. Soube até que alguém que portou isso para Windows, mas não sei se existe de fato. Mas algo conio dos anos 80 escrita para DOS tem boa chance de ser obsoleto. scanf() para consumir dados do teclado também é fácil de listar. Mas obsoleta não é a palavra. Apenas é inadequada. scanf() é sensacional e foi escrita para ler dados formatados --- scan f ormatted data --- acho que por um dos maiores desenvolvedores de todos os tempos. É como um mini AWK dentro do C. Se você tem uma tabela de milhares de linhas com vários tipos de dados vai gostar de consumir tudo em umas 10 linhas usando scanf(). Mas não é pra ler entrada do teclado. Eu listaria como obsoleto em C qualquer programa interativo, desses que leêm do teclado e escrevem na tela, aquelas coisas ingênuas com menus e tal. Programas de console em modo texto no geral não dá mais pra taxar de obsoletos porque com a debandada dos computadores para a nuvem tudo vem mudando. Tem a necessidade de administrar essas máquinas com interfaces de texto e nem sempre arquivos JSON e XML ou YAML são suficientes e se vê alguma necessidade de programas rápidos para rodar nesses ambientes ou em contato com eles, já que do lado administrativo essas máquinas não tem outra interface em muitos casos. Essa é a a razão eu acho de a Microsoft por exemplo ter gasto milhões de dólares em desenvolvimento de um novo modelo de console para Windows com o ConPTY a partir de 2017: Azure, Google Cloud, AWS, Heroku, containers... Taxar a linguagem C em si como obsoleta é um provável exagero. Me lembra de quantas vezes já ouvi e li que "o dinheiro de papel ia acabar", que "os livros eram coisa do passado", que "as crianças hoje em dia sabem tudo de computador", que "o meu sobrinho sabe tudo de tecnologia" e coisas assim. O mercado de automação e eletrônica embarcada, os cross-compilers, a absurda quantia de software existente escrito em C, incluindo aí até algumas das propostas linguagens modernas muito adequadas para substituir C e que foram escritas em C e rodam em sistemas escritos em C. E quanto das appliances em uso na internet tiveram e tem firmware escrito em C? Acha que alguém escreve software para roteadores em puro Assembler? No mais alto nível de Python? Em java? Na verdade não. Software para 5G em Go? Provavelmente não.E as bibliotecas extraordinárias que permitem fazer tudo em Python, deste tortas e bolos, cuidar das crianças e pesquisa genética são em geral escritas em C... Coisas assim sugerem que a linguagem vai estar aí por um tempo ainda... -
Acho que é só esse o erro. Mas precisa ser descrito com mais precisão. eu acho: Para isso C tem o modificador ideal: const. Protege o programador dele mesmo. Considere: const float aliquota_INSS = .1F; // 10% const float aliquota_IR = 0.072F; // 90% * 8% const float aReceber = 0.828F; // 100% - 10% - 7.2% Essas coisas não vão mudar a menos de um erro como o que você cometeu aqui: INSS=INSS*num; IR=(num-INSS)*IR; saldof= num - (INSS+IR); saldof= num - (INSS+IR); Se usasse const o programa não ia compilar se você tentasse mudar o valor do INSS... E é muito melhor saber isso quando está compilando certo? Declarando como mostrei já pode usar uma operação só para calcular as parcelar para colocar no relatório. Não há propósito em ficar refazendo a mesma conta (1 - .1)*(1 - 0.08) porque sempre vai dar o mesmo resultado: 0.828, o saldo a receber. Eis suas declarações originais float num, saldoi, IR=0.08, INSS=0.1, saldof; int contador=0; char nome[40]; Se está começando agora a programar é possível evitar vícios ruins. Em geral se for trabalhar com isso vai ter que se sujeitar a códigos de ética da empresa, da escola ou do patrão mesmo. E aqui é só um forum e você não trabalha para mim mas em geral: não declare mais que uma variável por linha Se você sabe que algo é const declare const. De volta ao programa Veja essa conta por exemplo: saldoi = (num*0.07)+num; Claro que não precisa multiplicar e somar. Seu programa tem umas 4 variáveis: porque saldoi não é simplesmente salario? Porque leu num para depois calcular saldoi? Que tal salario = 1.07F * salario; // so isso // ou salario *= 1.07F; // uma chance a menos de digitar salario errado. // ideal para nomes de variaveis em polones uma vez que tenha mostrado o salario na tela não precisa mais do valor: siga o enunciado: então pode simplesmente corrigir o salario e continuar. Escreva seu programa em torno dos dados. Sempre em torno dos dados. E não programe nada antes de ter uma boa noção dos dados e do que vai fazer. Exemplo: em torno dos dados, um gabarito Você usa o próprio editor de texto do IDE, se usa um, ou o bloco de notas ou sei lá, e tenta: * 1 * 2 * 3 * 4 * 5 * 6 * 7 * 01234567890123456789012345678901234567890123456789012345678901234567890123456789 Salario Nome Original Novo INSS IR A Receber AAAABBBBCCAAAABBBBCCAAAABBBBCC -123456,78 -123456,78 -123456,78 -123456,78 -123456,78 AAAABBBBCCAAAABBBBCCAAAABBBBCC -123456,78 -123456,78 -123456,78 -123456,78 -123456,78 AAAABBBBCCAAAABBBBCCAAAABBBBCC -123456,78 -123456,78 -123456,78 -123456,78 -123456,78 AAAABBBBCCAAAABBBBCCAAAABBBBCC -123456,78 -123456,78 -123456,78 -123456,78 -123456,78 AAAABBBBCCAAAABBBBCCAAAABBBBCC -123456,78 -123456,78 -123456,78 -123456,78 -123456,78 Pois é: são só 6 colunas. Recortar e colar e alinha os títulos e textos e as vírgulas. As duas primeiras linhas são uma régua e tem os números das colunas certinhas. Conveniente. E aí você recorta direto para o programa. Em C? printf("%45s\n%30s %10s %10s %10s %10s %10s\n\n", "Salario", "Nome", "Original", "Novo", "INSS", "IR", "A receber"); Pois é: usando o tamanho dos campos ao invés de lutar com a barra de espaços a cada vez que sai torto. E nem vai sair torto. E se quer um campo alinhado à esquerda use "%-30" por exemplo. Mas não mexe nas strings. Acho que deu pra entender. E os dados? printf("%30s %10.2f %10.2f %10.2f %10.2f %10.2f\n", nome, v,v,-v,-v,v); Igualzinho. Recortar e colar. E que p0R$R$@ é esse v? um número grande. Só isso. Vou mostrar a seguir. Mas é em C++ Em C++ é mais chato porque os tamanhos vem em funções. Fica mais comprido. Mas tem o recurso de recortar e colar e se escrever em várias linhas... E o que importa é ter um gabarito. Veja cout << setw(46) << "Salario\n" << setw(30) << "Nome" << setw(11) << "Original" << setw(11) << "Novo" << setw(11) << "INSS" << setw(11) << "IR" << setw(11) << "A receber" << endl; Quando se segue um plano é mais fácil. setw(nn) determina o comprimento do próximo campo. E os dados? cout << fixed << setw(11) << setprecision(2) << func[f].salario << setw(11) << setprecision(2) << -func[f].salario * aliquota_INSS << setw(11) << setprecision(2) << -func[f].salario * aliquota_IR << setw(11) << setprecision(2) << func[f].salario * aReceber << endl; std::fixed? Isso determina que é para mostrar os float em decimal, não usar expoentes. setprecision() é o óbvio. E sai certinho? Provável. Agora sim vamos usar um programa com os dois printf() colados do gabarito #include <stdio.h> int main() { printf("%45s\n%30s %10s %10s %10s %10s %10s\n\n", "Salario", "Nome", "Original", "Novo", "INSS", "IR", "A receber"); const char* nome = "AAAABBBBCCAAAABBBBCCAAAABBBBCC"; const float v = 123456.89f; for(int i=0;i<5;i+=1) printf("%30s %10.2f %10.2f %10.2f %10.2f %10.2f\n", nome, v,v,-v,-v,v); printf("\n\n\n"); return 0; }; Que mostra Em C++? É só um gabarito. #include <iostream> #include <iomanip> using namespace std; int main() { cout << setw(46) << "Salario\n" << setw(30) << "Nome" << setw(11) << "Original" << setw(11) << "Novo" << setw(11) << "INSS" << setw(11) << "IR" << setw(11) << "A receber" << endl; const string nome = "AAAABBBBCCAAAABBBBCCAAAABBBBCC"; const float v = 123456.89f; for (int i = 0; i < 5; i += 1) cout << setw(30) << nome << setw(11) << setprecision(8) << v << setw(11) << setprecision(8) << v << setw(11) << setprecision(8) << -v << setw(11) << setprecision(8) << -v << setw(11) << setprecision(8) << v << endl; cout << "\n\n\n"; return 0; }; E funciona? Sim., Mas não leu os dados. Pois é: essa é a última de todas as coisas. Não é importante. Ler dados da console, menus, essas coisas que só atrasam. Criar o gabarito levou 5 minutos, os programas foram copiados do gabarito e ler os dados é só pra preencher um formulário. De volta aos dados: Em C++ vamos criar uma coisa mínima: uma classe class Pessoal { public: string nome; float salario; }; Tipo C. Sem nada. E declarar Pessoal func[3]; // le os caras for (auto& pessoa : func) { cout << "\nDigite seu nome: "; getline(cin, pessoa.nome); cout << "Digite seu salario: "; cin >> pessoa.salario; cin.ignore(80,'\n'); // le ate o fim da linha }; // for() É o que temos. Não vou colocar o programa em C e ficar comentando tudo porque estou cansado de escrever e acho que já deu pra entender o princípio de escrever EM TORNO DOS DADOS desde o início. Preenchendo o formulário: for (int f = 0; f < 3; f += 1) { cout << setw(30) << func[f].nome << setw(11) << fixed << setprecision(2) << func[f].salario; func[f].salario *= 1.07F; // aumento cout << fixed << setw(11) << setprecision(2) << func[f].salario << setw(11) << setprecision(2) << -func[f].salario * aliquota_INSS << setw(11) << setprecision(2) << -func[f].salario * aliquota_IR << setw(11) << setprecision(2) << func[f].salario * aReceber << endl; }; // for() Agora basta trocar no programa que usava o valor constante v pelo que foi lido no início e claro que vai dar certo e sair alinhado, porque já fizemos isso ANTES de programar:
-
C números divisíveis por 7 no intervalo de 0 a 100,
arfneto respondeu ao tópico de Jean Lucas Neves em C/C#/C++
O enunciado já é o caminho certinho. Você tem um livro? Seu curso adota ou recomenda um livro, imagino. Se não tem recomendo muito arrumar um. O problema: claro que você precisa de um vetor. Está escrito lá. Tem no máximo 100 números mas então algo como 100 / 7 podem ser divisíveis por sete, certo? você pode partir dos 100 números ou fazer o simples que é seguir aquele conceito antigo de tabuada do 7 0,7,14,21,28,35,42,49,56,63,70,77,84,91,98 Sim, é só isso. Como você sabe que tem menos múltiplos de 7 do que números no total, é meio ingênuo escrever um loop de 100 números para pular 6 em cada 7, certo? imagino que tenha aprendido o que é um loop. C tem 4 possibilidades: while() for() do/while() e goto. for() é o mais simples aqui, e tem 3 partes: for(a;b;c); onde a,b e c são opcionais. Mas se estão presentes a é o início, b é a condição de fim e c é o incremento a cada vez que roda o código que está entre as chaves, que pode ser... nada. for( int a = 0; a<10; a+=1) { // algo; }; então esse acima faz alguma coisa dentro de { } até (a<10). E a cada iteração --- loop -- soma um em a. No popular roda aquele trecho de código 10 vezes. No seu caso eu já te mostrei a, b e c. Então você declara um vetor de 15 números, pega um comando desses "for" e preenche o tal vetor com números que estão acima: os chamados múltiplos de 7. Desde o início da alfabetização sabe o incremento: 7. O início está na tabuada: 0. O limite está no enunciado: 100 adicionado 0 minutos depois Como procurou? Achou o que? -
C++ Utilização de string para representar textos
arfneto respondeu ao tópico de Sheila Macedo em C/C#/C++
@devair1010 Note que no tópico #10 eu também sugeri algo como const string str[4] = { "ovo","andre","os","amarelo" }; cout << "\ncaso 1: mostra so as letras na saida\n\n"; for (const auto& uma : str) { int n = uma.size() / 2; cout << "\"meio\" de '" << uma << "' = "; if (!(uma.size() % 2)) cout << uma[n - 1]; cout << uma[n] << endl; }; // for() E no exemplo que eu mostrei inicialmente era pra ler uma única string. Acho que essa maneira acima é a mais curta de escrever isso. Sobre essa chamada: setlocale (LC_ALL, ""); Note que eu não usei acentos em "andre". Quando você chama setlocale() assim está dizendo ao programa para usar as configurações do sistema em que o programa está rodando. Só que você não sabe qual é a configuração de locale. Em geral é problema. Windows 10 por exemplo entra sempre com a página 850, onde o 'é' vai virar "Ú". Veja esse trecho numa máquina comum: C:\Users\toninho\source\repos\ConsoleApplication29\Debug>chcp Página de código ativa: 850 C:\Users\toninho\source\repos\ConsoleApplication29\Debug>ConsoleApplication33 caso 1: mostra so as letras na saida "meio" de 'ovo' = v "meio" de 'andrÚ' = d ... C:\Users\toninho\source\repos\ConsoleApplication29\Debug>chcp 1252 Página de código ativa: 1252 C:\Users\toninho\source\repos\ConsoleApplication29\Debug>ConsoleApplication33 caso 1: mostra so as letras na saida "meio" de 'ovo' = v "meio" de 'andré' = d ... Apaguei as linhas dos outros testes acima, claro. O que --- eu acho --- importa é entender que se: - provavelmente o melhor é apenas nem tentar usar acentos.É irrelevante aqui - se vai usar então salve o locale chamando getlocale(), mude para português com setlocale(), mostre os valores e restaure ao final com o valor de locale que você salvou. - o fato de sair ok em seu computador não quer dizer que vai sair assim em outros. Ou mesmo no seu depois que você rodar um programa que, assim como o seu eventualmente, muda coisas e não restaura, como fontes da console, cores ou atributos regionais Outra opção: criar uma string com o resultado As outras opções de que falei eram criar uma string com o valor, algo que o enunciado não exige, apenas para mostrar o overload do operador '+' no caso da classe string em C++, tipo java: // opcao 2 sem usar funcoes cout << "\ncaso 2: cria uma string\n\n"; for (const auto& uma : str) { string saida = ""; int len = uma.length(); if (len > 0) { if (len % 2 == 1) saida += uma[len / 2]; else { saida += uma[(len / 2) - 1]; saida += uma[(len / 2)]; }; cout << "String: '" << uma << "'\tTamanho: " << len << "\tMeio: '" << saida << "'\n"; }; // if }; // for() Outra opção: derivar string e cria o método meio cout << "\ncaso 3: deriva classe 'string' e cria metodo meio()\n\n"; for (const auto& uma : str) { StringNova valor(uma.c_str()); cout << "String: '" << valor << "'\tTamanho: " << valor.length() << "\tMeio: '" << valor.meio() << "'\n"; }; // for() Esse é o princípio de classes afinal e a linguagem foi escrita para isso. Bem mais fácil de ler, já que basta escrever valor.meio() e ter a string. Precisaria de algo assim class StringNova : public std::string { public: string meio() { if (size() == 0) return ""; if (size() % 2 == 1) return substr(size() / 2, 1); else return substr((size() / 2) - 1, 2); }; StringNova() : string("") {}; StringNova(const char* s) : string(s) {}; }; Claro que na prática teria que ser mais elaborado Clique no botão para ver o programa completo E aqui para ver a saída, que é a mesma de antes -
C++ Erro do compilador na programação web
arfneto respondeu ao tópico de Daniel Bittencourt em C/C#/C++
completando o desenho que mandei E veja o exemplo na documentação, onde eu te disse. Vai ajudar. WSAstartup() é só o começo da negociação pra usar sockets em windows. adicionado 19 minutos depois De todo modo entenda que não é um erro do compilador não é programação web Um erro de compilação seria algo com os parâmetros para a chamada, ou função não encontrada devido à configuração de includes ou algo assim. Afinal está usando gcc como compilador. -
C++ Erro do compilador na programação web
arfneto respondeu ao tópico de Daniel Bittencourt em C/C#/C++
O que é "programar na web"? WSAstartup() serve apenas para iniciar Windows Sockets, a camada TCP/IP no Windows. Isso não tem a ver com programar na web exceto pelo fato de TCP/IP ser a camada de transporte em uso na internet. Você pode usar sockets para comunicar programas que rodam na sua máquina, ou para imprimir em certas impressoras, ou para transferir arquivos para o computador ao lado... O que seria uma "tag"? Nada tem a ver com o compilador. Apenas com o link. Precisa ver como esse seu ambiente identifica aquela biblioteca. Provavelmente nesse formulário acima Talvez devesse usar software da Microsoft para escrever coisas para Windows Sockets. Aí não teria que configurar nada. Tem um exemplo de uso em https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsastartup onde tem a documentação toda. -
C++ Utilização de string para representar textos
arfneto respondeu ao tópico de Sheila Macedo em C/C#/C++
No caso de "amarelo", por favor entenda o que foi discutido e o que expliquei: Eu por exemplo postei 3 soluções acima... Olhe lá e me diga se não entendeu e tento explicar de outro modo... Lá no tópico clique no botão e vai ver o programa com as 3 versões para a solução, e veja o que expliquei -
C++ Utilização de string para representar textos
arfneto respondeu ao tópico de Sheila Macedo em C/C#/C++
Estaria errado. O tamanho é ímpar então no meio só tem uma letra. Foi bem comentado acima. E tem ao menos 5 exemplos completos -
Não conhecia essa definição de "recursão linear". E o que seria isso? Em particular "um código fibonacci é numeros primos com recursividade em c, mas dentro do swich case"? Não consegui entender. Esse era um tópico de DEZ anos atrás. Porque ressuscitou isso ao invés de postar um tópico novo e algum código e uma descrição mais precisa do que quer fazer? Curiosamente até hoje só se vê essa solução do autor mesmo: int fibonacci (int n) { if (n == 1 || n == 0) return n; else return fibonacci(n-1) + fibonacci(n-2); } Veja a solução em https://www.programmingsimplified.com/c-program-generate-fibonacci-series int f(int n) { if (n == 0 || n == 1) return n; else return (f(n-1) + f(n-2)); } Em 2020, agosto, 31. A mesma que está em https://www.geeksforgeeks.org/program-for-nth-fibonacci-number/ hoje. E em https://www.tutorialspoint.com/data_structures_algorithms/fibonacci_recursive_program_in_c.htm E algumas em https://stackoverflow.com/ como essa https://stackoverflow.com/questions/42557573/recursive-fibonacci-in-c-plain-simple mas com problemas. Estranho até porque parece que não é uma solução muito boa. A cada recursão chamar duas vezes a própria função cresce muito rápido em complexidade. Não vi nenhuma usando uma simples recursão, e não sei como chegaram a uma solução usando duas chamadas. Mas achei interessante. É como @Mauro Britivaldo disse. Como o código recursivo é reentrante há duas maneiras tradicionais de passar contexto: passando um argumento, tipo uma bola de neve usando variáveis estáticas e algum tipo de inicialização e reinicialização pra poder chamar de novo durante uma mesma execução do programa Nesse caso aqui usar variáveis estáticas é mais simples. Mas acho que precisa de 4 delas. E transformar o loop da programação tradicional em recursão. E ter um cuidado extra com o overflow. O maior que cabe em um int acho que é o 93: fib(93) = 7540113804746346429 Acima disso já precisa arrumar outra representação...
-
C++ Utilização de string para representar textos
arfneto respondeu ao tópico de Sheila Macedo em C/C#/C++
O exemplo do tópico tem esse erro no exemplo do "amarelo". Só isso. @Midori Outro exemplo: note que o loop de seu exemplo string str[4] = { "ovo","andre","os","amarelo" }; for(int i = 0, n = 0;i<4;i++){ n = str[i].size()/2; cout << "Valor do elemento " << i+1 << " = "; if(!(str[i].size() % 2)){ cout << str[i][n - 1]; } cout << str[i][n] << endl; } que mostra Valor do elemento 1 = v Valor do elemento 2 = d Valor do elemento 3 = os Valor do elemento 4 = r pode ser trocado por algo como string str[4] = { "ovo","andre","os","amarelo" }; for (auto uma : str) { int n = uma.size() / 2; cout << "\"meio\" de '" << uma << "' = "; if (!(uma.size() % 2)) cout << uma[n - 1]; cout << uma[n] << endl; }; // for() que mostraria 'meio' de "ovo" = "v" 'meio' de "andre" = "d" 'meio' de "os" = "os" 'meio' de "amarelo" = "r" que pode ser um pouco mais fácil de ler, o programa e o resultado. Claro, estender string como eu mostrei antes é o mais legível e moderninho
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