Ir ao conteúdo
  • Cadastre-se
johnkaos

C Manipulação de Arquivos csv

Posts recomendados

Olá,boa noite,sou novo em programação,e não estou conseguindo resolver um Código de C,onde tenho que pré - processar os dados de dois arquivos CSV e formar um único arquivo,com o seguinte formato : N de paises na primeira linha e depois País, GDP, Life Satisfaction. Já faz uma semana que tento fazer e não sei como proceder,alguém pode me ajudar?

Os dois arquivos csv estão em anexo,caso alguém queira ver.

 

gdp_per_capita.csv oecd_bli_2015.csv

Compartilhar este post


Link para o post
Compartilhar em outros sites

de uma olhada nessa biblioteca libcvs.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Acho que antes precisa dar uma olhada nos dados que tem e ver como foi extraído cada um desses arquivos.

 

CSV é um formato absolutamente estabelecido e era algo como o pen-drive dos anos 70. Importei seus dados em uma planilha, o meio mais simples de conferir. File | Import | upload no Google Sheets por exemplo leva segundos...

 

A primeira linha tem o nome dos campos. Depois temos uma linha para cada registro, somente com os dados.

 

Veja o seu caso:

 

Arquivo 1

"LOCATION","Country","INDICATOR","Indicator","MEASURE","Measure","INEQUALITY",
"Inequality","Unit Code","Unit","PowerCode Code","PowerCode","Reference Period Code",
"Reference Period","Value","Flag Codes","Flags"

esta é a linha dos campos (com umas quebras de linha pra facilitar a leitura). Como há campos com espaços então precisa mesmo das aspas. O delimitador claramente é a vírgula, mas vendo os campos fica claro que tem algo errado: aparecem campos duplicados e na linha de dados a situação não é melhor... A correspondência entre campos e dados é claro de 1 para 1, mas veja a linha para a Australia:

"AUS","Australia","HO_BASE","Dwellings without basic facilities",
"L","Value","TOT","Total","PC","Percentage","0",
"units",,,1.1,"E","Estimated value"

Nessa linha só deve ter dados...

 

Arquivo 2

 

Esta é a linha dos campos (com umas quebras de linha pra facilitar a leitura)

Country	Subject Descriptor	Units	Scale	
Country/Series-specific Notes	2015	
Estimates Start After

E veja uma linha de dados

Afghanistan	Gross domestic product per capita, current prices	U.S. dollars	Units	See notes for:  Gross domestic product, current prices (National currency) Population (Persons).	599.994	2013

Qual seria o delimitador? Como um programa vai extrair esses dados?

 

Exemplo de um arquivo válido

 

Compare com isto

nome,"O endereco", "valor do lote"
"Nome 1", "Rua 1", "1.000.000"
"Nome 2", "Rua 2", "2.000.000"
"Nome 3", "Rua 3", "1.030.000"
"Nome 4", "Rua 4", "1.400.000"

E veja o resultado numa planilha do Sheets:
 

testeCSV.png.6bab07a4307238d41f25b82b9711114a.png

 

Viu o efeito das aspas e a mecânica? Seus arquivos tem que ter esse comportamento antes de você programar qualquer coisa. 

O tratamento desses arquivos em C ou qualquer outra linguagem é simples. Não acho que precise de qualquer biblioteca exceto por exemplo stdlib.h ou string.h

 

Mas precisa rever os dados.

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto Então o pre-tratamento teria que ser feito no excel,por exemplo? organizando e depois partindo pra outra parte? Se organizar pelo excel dá certo? ou é preciso organizar pelo compilador?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não. Apenas use esses programas --- qualquer programa que leia csv --- para refinar os seus arquivos de entrada pois estão errados.

 

Um programa de computador  é muito mais flexível, em especial porque você mesmo o está escrevendo. Uma vez que tenha os arquivos no formato correto.

 

No Google Sheets é mais fácil importar seus dados que no Excel. Importar dados no Excel --- ou no Office de um modo geral ------ é muito mais flexível, tem uma espécie de assistente. Excelente quando precisa disso, mas aqui não é o caso. Basta File | Import | Upload e pode até arrastar o arquivo csv para a janela do Sheets. Difícil competir.

 

Entendeu a diferença entre o arquivo que te mostrei e os arquivos que você tem? O segundo por exemplo é praticamente inútil. Como extraiu esses dados? Tem os arquivos originais? O primeiro tem todos aqueles campos duplicados, de pouco serve também.

 

Se não tem mais acesso aos originais talvez possa -- se encontrar um padrão --- corrigir os arquivos de entrada antes de importar em seu programa, usando uma fase inicial em seu programa C.

 

Como te disse, esse era o pen drive dos anos 70/80 e a gente usava isso para muitas coisas. Coisas como mala direta, bancos de dados e programas de escritório. Se o seu delimitador é ou pode ser a ', ' e pode colocar aspas nos campos que tem espaço qualquer programa trata isso. De um banco de dados Oracle ao seu programa da PIMACO de imprimir etiquetas, que naquela época vinha gravado em um diskette de 1.44 megabyte :) 

 

Mas tem que seguir o formato: valores separados por vírgula. Cada linha é um registro. A primeira linha em geral é especial e tem os nomes dos campos. Um número idêntico de campos existe em cada linha. Valores que não estão presentes são indicados por delimitadores consecutivos. O delimitador em geral é a vírgula, o C de CSV. O S é de separados e o V de valores, Comma Separated Values.

 

Postei muitos detalhes sobre isso em um tópico recente aqui neste forum 

 

Novo Exemplo

 

Esse arquivo

"Campo 1", "Campo 2", "Campo 3"
1,2,3
,,
1,,3
,,3

Gera 

outro.png.30a8798a8dffb9b61e72ba4f6f1c9102.png

 

Assim recomendo voltar aos seus arquivos de entrada e colocá-los de acordo com o formato. 

Se quer escrever o programa em C ou C++ primeiro também pode ser, e pode postar aqui se precisar de algo. Apenas não vá testar com os seus arquivos originais porque eles tem problemas. 

 

Qualquer programa gera csv. Pode criar uma planilha em excel com seus valores válidos e testar assim seu programa C. Você sabe o que deveria estar naqueles dois arquivos CSV que postou. Os dados. Só isso. E não é isso que está lá.

 

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto  Peguei ambos do Git:

https://github.com/ageron/handson-ml/tree/master/datasets/lifesat

 

Porém,de acordou com o que me disse,seria bem melhor criar um arquivo Original,com as fontes citadas:

 

http:// http://stats.oecd.org/index.aspx?DataSetCode=BLI

 

http://goo.gl/j1MSKe

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sim. Ou quase isso.

 

Sobre o primeiro arquivo:

 

A função de exportação do Better Life Index está errada. Então você precisa corrigir por sua conta. O gênio que programou aquilo não percebeu que os títulos das colunas iriam se perder e zoar o CSV, e não está exportando quase nada dos dados. A culpa no entanto é de quem distribuiu os títulos dos campos por nada menos que TRÊS linhas. Claro que ia dar m#$%a.

 

Não perca seu tempo com esse.

 

Veja o que tem em seu arquivo para a Austrália:

"AUS","Australia","JE_LMIS","Labour market insecurity","L","Value","TOT",
"Total","PC","Percentage","0","Units",,,5.4,,

E o que tem no BLI

 

BLI.thumb.png.f73d835e9c75aec6a7460bb6087d62f4.png

 

Seu arquivo não só para na coluna I como ainda zera a J com aquele ,, e os dados vão até AA, 17 colunas

 

No entanto parece que o XML e a planilha excel exportada estão ok, apesar do formato estar errado também e dar uma série de mensagens. No Excel online não abre. A versão desktop acaba abrindo, ao menos a última versão de Excel que é a única que eu tenho. E a partir do Excel se pode gerar o csv correto e continuar com o seu programa... Ou usar o XML.

 

O segundo arquivo

 

Esse tem apenas 7 colunas mas o arquivo CSV não tem sequer os delimitadores. Tem os mesmos problemas para abrir com o Excel mas acaba abrir e aí pode gerar um csv correto

 

Porque não posta a  especificação do resultado que quer? Quer um filtro? uma projeção?

 

 

 

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto  O objetivo: https://prnt.sc/qr0xc5

 

E aqui o que fiz até agora,o que não consigo entender é essa parte de manipular o CSV,e ai,salvar só a parte necessária.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
/*vetor de struct*/
typedef struct{
int qntd;
char pais[30];
float gdp;
float satisfaçao_vida;
}lgoritmo_qualidade_de_vida
algoritmo_qualidade_de_vida pib[193];



void leArquivocsv(algoritmo_qualidade_de_vida *pib)

/*struct alocada.*/
int main(int argc , char *argv)
{
qtd_pais = 193;
pib = struct algoritmo_qualidade_de_vida * malloc (qtd_pais * sizeof(struct algoritmo_qualidade_de_vida));
system("PAUSE");
return 0;
}


void leArquivocsv(algoritmo_qualidade_de_vida *pib) /* função para a abertura do arquivo csv. */
{
    int i;
    FILE *arquivo;
    arquivo = fopen("\\.csv","r");
for (i=0; i<108 ; i++)
    {

        fscanf(arquivo, "%d[^,\n]", &pib[i].qntd);
        fscanf(arquivo, "%[^,\n]", &pib[i].pais);
        fscanf(arquivo, "%f[^,\n]", &pib[i].gdp);
        fscanf(arquivo, "%f[^,\n]", &pib[i].satisfaçao_vida);

}
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você entendeu o que eu expliquei? Entendeu que os dados estão ERRADOS? Em formato E conteúdo?

 

Você tinha tentado ao menos ler o conteúdo daqueles arquivos?

 

Você tem um arquivo com 17 campos e outro com 7. Os campos --- se os arquivos estivessem ok ---  seriam separados por virgula e fscanf() pode tratar isso quase no automático.

 

Você sequer precisa importar os CSV na verdade. Nenhum dos dois.

 

De todo modo seria mais fácil você especificar formalmente o resultado que espera.

 

No geral:

 

Você vai ter um arquivo mestre, provavelmente o de 7 campos, e vai completar com algo que vai ler do outro, imagino. Os campos que vai ler de cada arquivo são separados por vírgula (deveriam ser)

 

Exemplo:

 

"Work-Life Balance: Time Devoted to leisure and personal care (in hours)"  Para a Austrália está definido como 14,35 horas no BLI, e é o campo 17. Em todas as linhas. Só isso. A linha da Austrália é a primeira, e o nome do país é o primeiro campo.

Então basta abrir o arquivo, encontrar o país (campo 1) e encontrar os dados de que precisa na linha do país, contando as vírgulas até o valor e pronto.

 

claro que você pode criar uma estrutura para cada tabela e importar direitinho todos os dados, mas se não vai fazer um trabalho extenso com isso não há razão. Apenas leia os dados e derive sua tabela.

 

 

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto Eu entendi sim,já tinha tentando ler o conteúdo dos arquivos,tentando abrir em um arquivo de teste,porém  não funcionava.

Vou tentar organizar os dois pelo excel,como citado,caso não funcione,vou criar um novo arquivo csv,importando os dados do site original.

Obrigado :D

adicionado 4 minutos depois

Sobre o por que vou tentar ajeitar os arquivos,é que o exercício pede que processe os dois arquivos CSV citados e forme um único,acho que se fizer um novo arquivo csv orignal da fonte,o exercício pode ficar como errado...

Compartilhar este post


Link para o post
Compartilhar em outros sites
2 minutos atrás, johnkaos disse:

@arfneto Eu entendi sim,já tinha tentando ler o conteúdo dos arquivos,tentando abrir em um arquivo de teste,porém  não funcionava.

Vou tentar organizar os dois pelo excel,como citado,caso não funcione,vou criar um novo arquivo csv,importando os dados do site original.

Obrigado :D

 

Acho que não entendeu.

 

A função de exportação do site original está ERRADA. Do BLI. Não vai funcionar. Se sabe como fazer exporte do site para o Excel e no Excel simplesmente corrija o valor do header na linha 1/2/3: a linha 1 tem que ter exatamente 17 campos, que é o que tem nas outras 3000 linhas....

 

Depois de reparar o erro exporte a SUA planilha corrigida como um CSV e use em seu programa.

 

E o último campo da linha 1 pra ajudar já te falei que tem que ser o 14,35 :D 

 

O outro arquivo tem que ser corrigido também, o de 7 campos. Tem que ficar como os exemplos que te mostrei.

 

Para testar o seu programa bastam dois arquivos de duas linhas cada um. Acho que já entendeu isso. Um com 17 campos e outro com 7 campos, e podem ser numerados como os exemplos que te dei...

adicionado 33 minutos depois

Talvez não tenha familiaridade com essas ferramentas, então eis dois arquivos corrigidos mas com poucos dados

O BLI só com dois países

Country;;;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24
Australia;;;..;20;..;32759;427064;5,4;73;1,31;49126;95;81;502;21;5;93;2,7;91;82,5;85;7,3;63,5;1,1;13,04;14,35
Austria;;;0,9;21;1,6;33541;308325;3,5;72;1,84;50349;92;85;492;17;16;92;1,3;80;81,7;70;7,1;80,6;0,5;6,66;14,55

E o outro com dados de alguns países incluindo, claro, esses dois

Country;Subject Descriptor;Units;Scale;Country/Series-specific Notes;2015;Estimates Start After
Afghanistan;Gross domestic product per capita, current prices;U.S. dollars;Units;See notes for:  Gross domestic product, current prices (National currency) Population (Persons).;599.994;2013
Albania;Gross domestic product per capita, current prices;U.S. dollars;Units;See notes for:  Gross domestic product, current prices (National currency) Population (Persons).;3,995.383;2010
Algeria;Gross domestic product per capita, current prices;U.S. dollars;Units;See notes for:  Gross domestic product, current prices (National currency) Population (Persons).;4,318.135;2014
Angola;Gross domestic product per capita, current prices;U.S. dollars;Units;See notes for:  Gross domestic product, current prices (National currency) Population (Persons).;4,100.315;2014
Antigua and Barbuda;Gross domestic product per capita, current prices;U.S. dollars;Units;See notes for:  Gross domestic product, current prices (National currency) Population (Persons).;14,414.302;2011
Argentina;Gross domestic product per capita, current prices;U.S. dollars;Units;See notes for:  Gross domestic product, current prices (National currency) Population (Persons).;13,588.846;2013
Armenia;Gross domestic product per capita, current prices;U.S. dollars;Units;See notes for:  Gross domestic product, current prices (National currency) Population (Persons).;3,534.860;2014
Australia;Gross domestic product per capita, current prices;U.S. dollars;Units;See notes for:  Gross domestic product, current prices (National currency) Population (Persons).;50,961.865;2014
Austria;Gross domestic product per capita, current prices;U.S. dollars;Units;See notes for:  Gross domestic product, current prices (National currency) Population (Persons).;43,724.031;2015
Azerbaijan;Gross domestic product per capita, current prices;U.S. dollars;Units;See notes for:  Gross domestic product, current prices (National currency) Population (Persons).;5,739.433;2014
The Bahamas;Gross domestic product per capita, current prices;U.S. dollars;Units;See notes for:  Gross domestic product, current prices (National currency) Population (Persons).;23,902.805;2013
Bahrain;Gross domestic product per capita, current prices;U.S. dollars;Units;See notes for:  Gross domestic product, current prices (National currency) Population (Persons).;23,509.981;2014

 

Assim pode entender e desenvolver seu programa...

 

Note que a vírgula foi substituída por ';' e acho que sabe porque... Estou usando uma máquina em que o ponto decimal está configurado para ',' e assim ao exportar os dados claro que tinha que usar outro delimitador... No Brasil se exportar campos numéricos como csv teria que por os dados entre aspas porque o ponto decimal aqui é vírgula. Eu assino o Office 365 mas a versão que está nesse micro é em inglês. Uma zona. Talvez a versão em português use as aspas.

 

O que você tem que fazer? Se quiser apenas troque o nome dos campos na primeira linha para o que quer usar em seu programa, se for importante

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto  o que achou dos arquivos CSV?

Eu dei uma editada nos arquivos,pib1 e gdp são diferentes,um com 6 e outro com 7 campos,qual acha que ficará melhor?

sobre 

sobre o Header e os dois campos para country,estão de acordo com o site,importei pelo Excel,

 

pib1.csv

gdp.csv

qualidade.csv

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, johnkaos disse:

No primeiro arquivo pra que serve o campo Header, que vale Unit para TODOS os registros? Porque dois campos idênticos para Country?
 

country.png.2dbbe51451b374565df006317b829b65.png


Qual o sentido da primeira linha do segundo arquivo? Todos os campos tem o mesmo nome

Shaded cells indicate IMF staff estimates;Shaded cells indicate IMF staff estimates;Shaded cells indicate IMF staff estimates;Shaded cells indicate IMF staff estimates;Shaded cells indicate IMF staff estimates;Shaded cells indicate IMF staff estimates

Você ao menos tentou importar isso no Sheets como eu te expliquei?

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto  Usei o excel,a publicação foi editada... 

 

2 horas atrás, johnkaos disse:

@arfneto  o que achou dos arquivos CSV?

Eu dei uma editada nos arquivos,pib1 e gdp são diferentes,um com 6 e outro com 7 campos,qual acha que ficará melhor?

sobre 

sobre o Header está de acordo com o site.

 

pib1.csv 35 kB · 1 download

gdp.csv 34 kB · 0 downloads

 

37 minutos atrás, arfneto disse:


Qual o sentido da primeira linha do segundo arquivo? Todos os campos tem o mesmo nome


Shaded cells indicate IMF staff estimates;Shaded cells indicate IMF staff estimates;Shaded cells indicate IMF staff estimates;Shaded cells indicate IMF staff estimates;Shaded cells indicate IMF staff estimates;Shaded cells indicate IMF staff estimates

Você ao menos tentou importar isso no Sheets como eu te expliquei?

 

Removida,e editei o arquivo,depois de importado pelo excel.

 

qualidade.csv

Compartilhar este post


Link para o post
Compartilhar em outros sites

Aí sim! 

O problema da planilha do bli é que há nada menos que tres línhas de títulos, por questão de agrupamento da visualização. E faz sentido. Mas na hora de importar é melhor você simplesmente numerar um a um e colocar talvez um texto mais significativo y nas colunas de que precisa 

 

Aquele que eu te mostrei está correto... 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto  Pode me ajudar com um problema de código?? 

 

image.thumb.png.e195f6d3d2955a103c245ed38ee7bc24.png

image.thumb.png.2ada697669a34e04c2d5bbdb06802ade.png

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>

struct auxiliar{
char aux1[25];
char aux3[15];
int aux2;
char paises[30];
char paisaux[30];
float gdp_perc;
float satisfacao;
};

struct gdpperc{
int qntd;
char pais[30];
float gdp;
float satisfacao_vidareal;
float satisfcao_vidacalc;
float erro;
};
void leArquivoum(struct auxiliar *auxs);
void leArquivodois(struct auxiliar *auxs);
void criacaodeumcsv(struct auxiliar *auxs);
void leArquivocsv(struct gdpperc *pib);

int main (int argc , char *argv)
{
int qntda;
int qntd;
qntda = 189;
struct auxiliar *auxs = malloc (qntda * sizeof(struct auxiliar));
free(auxs);
printf("informe a quantidade de paises que deseja usar: \n");
scanf("%d",&qntd);
struct gdpperc *pib = malloc (qntd * sizeof(struct gdpperc));
pib->qntd = qntd;
system("PAUSE");
return 0;
}

void leArquivoum(struct auxiliar *auxs){
int i;
FILE *arquivoum;
arquivoum = fopen("C:\\Users\\John\\Desktop\\trabalho\\gdp.csv","r");
fscanf(arquivoum, "%[\n]");
for (i=0; i< 189; i++)
{
    fscanf(arquivoum, "%[^;]", &auxs[i].paises);
    for(int j=0; j < 4; j++){
    fscanf(arquivoum, "%[^;]", &auxs[i].aux1);
    }
    fscanf(arquivoum, "%f[^;]", &auxs[i].gdp_perc);

}
  fclose(arquivoum);
}

void leArquivodois(struct auxiliar *auxs){

int k;

FILE *arquivo2;

arquivo2 = fopen("C:\\Users\\John\\Desktop\\trabalho\\qualidade.csv","r");
fscanf(arquivo2, "[\n]");
for(k = 0; k < 41; k++)
{
   for(int q=0;q<=1;q++)
   {
      fscanf(arquivo2, "%[^;]",&auxs[k].aux3);
   }
    fscanf(arquivo2, "%[^;]",&auxs[k].paisaux);
   for(int l=0; l<21; l++){
    fscanf(arquivo2, "%d[^;]",auxs[k].aux2);
    }
    for(int i=0; i < 189; i++ ){
        while (strcmp (auxs[k].paisaux,auxs[i].paises) == 0);
        {
        fscanf(arquivo2, "%f[^;]", &auxs[i].satisfacao);
        }
    while (strcmp (auxs[k].paisaux,auxs[i].paises) != 0);
    {
    auxs[i].satisfacao = 0;
    }
    }

}
  fclose(arquivo2);
}


void criacaodeumcsv(struct auxiliar *auxs){
int indice;
indice = 189;
FILE *arquivof;
arquivof = fopen("C:\\Users\\John\\Desktop\\trabalho\\primeiroresult.csv","w");
    fprintf(arquivof,"%d \n", &indice);
for(int i=0; i < 189; i++){
fprintf(arquivof, "%s", &auxs[i].paises,auxs[i]);
fprintf(arquivof, "%f", &auxs[i].gdp_perc);
fprintf(arquivof, "%f \n ", &auxs[i].satisfacao);
}
fclose(arquivof);
}

void leArquivocsv(struct gdpperc *pib)/* função para a abertura do arquivo csv. */{
float teta0 = 2.5;
float teta1 = 1;
float n = 0.1;
float eam;
int i;
    FILE *arquivofinal;
   arquivofinal = fopen("C:\\Users\\John\\Desktop\\trabalho\\primeiroresult.csv","r");
for (i=0; i < pib[i].qntd ; i++)
    {

        fscanf(arquivofinal, "%d[^,\n]", &pib[i].qntd);
        fscanf(arquivofinal, "%[^,]", &pib[i].pais);
        fscanf(arquivofinal, "%f[^,]", &pib[i].gdp);
        fscanf(arquivofinal, "%f[^\n]", &pib[i].satisfacao_vidareal);

}
for (i=0; i < pib -> qntd; i++ )
{
    arquivofinal = fopen("C:\\Users\\John\\Desktop\\trabalho\\resultadofinal.csv","w");
if (pib[i].satisfacao_vidareal != 0 ){
    for (int s = 0;s < 100;s++){
       pib[i].satisfcao_vidacalc = teta1 + teta0 * pib[i].gdp;
        pib[i].erro = pib[i].satisfcao_vidacalc - pib[i].satisfacao_vidareal;
        teta0 = teta0 + n * pib[i].erro * pib[i].gdp;
        teta1 = teta1 + n * pib[i].erro * pib[i].gdp;
    }
    }
eam = pib[i].satisfcao_vidacalc - pib[i].satisfacao_vidareal / pib[i].qntd;


    fprintf(arquivofinal, "%s,", &pib[i].pais);
    fprintf(arquivofinal, "%f,", &pib[i].gdp);
    fprintf(arquivofinal, "%f,", &pib[i].satisfcao_vidacalc);
    fprintf(arquivofinal, "%f \n", &pib[i].satisfacao_vidareal);
    }
fprintf(arquivofinal, "%Erro absoluto Médio: %f", &eam);
fclose(arquivofinal);
}

O código compila normalmente,porém não forma os dois arquivos csv...

e a outra duvida:

 

eu separei os países que tem ou não life_satisfaction,porém não faço ideia de como estimar o valor dos outros 😕image.thumb.png.a1506f3a01306f7cf808901426768dd0.png 

gdp.csv qualidade.csv

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá!

 

Muito ruim esse enunciado. Acho que podiam pensar um pouco mais formalmente ao escrever uma especificação de exercício.

enunciado.png.9160c990b2a4c64f25e8fa30143bfc84.png

os dados devem ser pré-processados? Então você recebeu por exemplo esse gdp.csv junto com o enunciado? Ou instruções de como obter isso?

 

Citação

"Formar um único arquivo CSV contendo a quantidade de países na primeira linha"

 

Sério? Está errado. Acho que já entendeu que um arquivo CSV é uma tabela (X,Y) e TODAS as X linhas tem Y colunas. Por definição desde sempre. Se tem uma linha inicial com o total de países não é um arquivo CSV

 

Se você vai alocar dinamicamente um vetor de structs, digamos com uma para cada país, não precisa saber antes o valor de N: basta esperar acabar o arquivo de entrada, por definição.

 

Repetir entre 50 e 100 vezes quer dizer o que? Não vai ter uma única linha para cada país? Isso quer dizer entre 50 e 100 países? Sua tabela parece ter 189 países. Não é fixo?

 

Life Satisfaction Real está no arquivo de entrada. E o Life Satisfaction Calculado deve ser algo que você aprendeu, certo? E deve ter um valor de theta envolvido já que aparece em seu código. Esse é o valor de theta mencionado aqui:

theta.png.300eabc9ccc46c408d65b13a5f5d1b75.png

A última linha deve ter o EAM do LS? OK, então a saída não é um arquivo CSV também...

De todo modo o calculo é trivial: apenas a média das diferenças em módulo dos índices para cada país.

 

Sobre seu programa:

 

Não sou eu quem vai julgar seu trabalho, se isso é um projeto de escola, mas alocar dinamicamente um vetor de structs não é bem alocar EXATAMENTE 189 no início do programa e pronto. E você aloca e libera na linha seguinte. Que pretende? Se liberou não vai usar mais...

 

A ideia é:

 

- você define uma struct igualzinho ao que vai ter na saída

-  aloca uma ao ler cada país,

- preenche com o que tem de dados

- calcula o que falta: o LFC

- acumula a diferença em módulo pra calcular o EAM no final

- e repete isso para cada país

 

Depois ao final 

 

- grava o header do csv

- grava uma linha do csv para cada struct do seu vetor

- chama free() e libera as structs

- calcula o EAM e grava na última linha, de modo que seu CSV não será mais um csv :D 

 

Eis a definição de csv direto do IETF

https://www.ietf.org/rfc/rfc4180.txt

 

Note que não é um standard IETF porque o formato já estava estabelecido décadas antes do IETF, já que o I é de ... internet.

 

Teve uma discussão sobre isso semanas atrás nesse mesmo forum, e tem lá mais alguns exemplos e detalhes, Não foi algo assim produtivo, mas pode ser útil

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto faltei especificar um pouco,foi mal...

sobre a primeira struct que aloquei com 189: É a struct auxiliar,apenas pra formar salvar os dados dos dois csv citados em uma,a segunda é que é a principal... e como já sei o número de países,aloquei logo na auxiliar kk...

sobre o calculo que preciso: existem países que não tem a satisfacao_vidareal,então eles não irão entrar no calculo...minha dificuldade é como encaixar eles,depois do calculo já feito.

sobre repetir 50 a 100 vezes,é repetir o procedimento do calculo... com fiz ai,um for de 0 a 99,rodando o calculo de cada país.

adicionado 4 minutos depois

Sobre de onde vem os arquivos,eles são aqueles dois arquivos do começo deste tópico que estavam todos errados e eu criei os dois novos... eles estão junto com o enunciado da questão.

Compartilhar este post


Link para o post
Compartilhar em outros sites
55 minutos atrás, johnkaos disse:

sobre a primeira struct que aloquei com 189: É a struct auxiliar,apenas pra formar salvar os dados dos dois csv citados em uma,a segunda é que é a principal

 

Melhor alocar uma a uma no formato da saida. Uma só. Não vejo a necessidade de mais de uma. E não precisa salvar esses dados dos csv. Apenas processe linha a linha como te falei no primeiro post

 

Entendeu o que eu disse sobre usar free() na linha seguinte ao malooc()? Não faz sentido.

 

56 minutos atrás, johnkaos disse:

sobre repetir 50 a 100 vezes,é repetir o procedimento do calculo... com fiz ai,um for de 0 a 99,rodando o calculo de cada país

 

Agora não entendi mesmo. Qual o propósito de repetir 50 a 100 vezes os mesmos cálculos para o mesmo país?

 

57 minutos atrás, johnkaos disse:

Sobre de onde vem os arquivos,eles são aqueles dois arquivos do começo deste tópico que estavam todos errados e eu criei os dois novos... eles estão junto com o enunciado da questão

 

Pois é. Ainda não estão assim bons, mas ao menos são formalmente corretos.

Compartilhar este post


Link para o post
Compartilhar em outros sites
10 minutos atrás, arfneto disse:

 

Agora não entendi mesmo. Qual o propósito de repetir 50 a 100 vezes os mesmos cálculos para o mesmo país?

os valores de theta vão mudando cada vez.

 

11 minutos atrás, arfneto disse:

Melhor alocar uma a uma no formato da saida. Uma só. Não vejo a necessidade de mais de uma. E não precisa salvar esses dados dos csv. Apenas processe linha a linha como te falei no primeiro post

 

Entendeu o que eu disse sobre usar free() na linha seguinte ao malooc()? Não faz sentido.

 

Eu retirei o free e coloquei só quando não ia usar mais a struct.

3 horas atrás, johnkaos disse:

printf("informe a quantidade de paises que deseja usar: \n"); scanf("%d",&qntd); struct gdpperc *pib = malloc (qntd * sizeof(struct gdpperc)); pib->qntd = qntd; system("PAUSE"); return 0;

Aqui é a struct principal,que vai alocar e ler o tanto de paises que o usuario pedir... 

Sobre o porque não tá gerando o arquivo csv,acha que pode ser por que não chamo as funções na main?

Compartilhar este post


Link para o post
Compartilhar em outros sites
5 minutos atrás, johnkaos disse:

os valores de theta vão mudando cada vez.

 

fascinante. É uma série convergente? Mas se os dados são os mesmos theta calcula o que?

 

6 minutos atrás, johnkaos disse:

Eu retirei o free e coloquei só quando não ia usar mais a struct.

 

Aí sim

 

6 minutos atrás, johnkaos disse:

Aqui é a struct principal,que vai alocar e ler o tanto de paises que o usuario pedir... 

 

Não são nem 200 linhas, não entendo porque selecionar por número. Até entenderia se o usuário oferece uma lista de países ou um critério baseado no GDP ou LSI, tipo os 30 com maor índice ou um cruzamento para tentar mostrar alguma correlação entre GDP e LSI. Mas um simples número que vai acabar na ordem alfabética parece bobagem. Não vai ensinar nada em termos de C ou de estatística :D

 

Não acho que precise de mais de uma struct, eu já disse.

 

Já sabe como calcular o valor que está faltando? 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
9 minutos atrás, arfneto disse:

fascinante. É uma série convergente? Mas se os dados são os mesmos theta calcula o que?

 

image.thumb.png.703ea2dfbda056d541966a7ced9a9247.png

 

10 minutos atrás, arfneto disse:

Já sabe como calcular o valor que está faltando? 

estou tentando ajeitar o fprintf,já que o arquivo formado do jeito que tava ficou praticamente um lixo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>

struct auxiliar{
char aux1[25];
char aux3[15];
int aux2;
char paises[30];
char paisaux[30];
float gdp_perc;
float satisfacao;
};

struct gdpperc{
int qntd;
char pais[30];
float gdp;
float satisfacao_vidareal;
float satisfcao_vidacalc;
float erro;
};
void leArquivoum(struct auxiliar *auxs);
void leArquivodois(struct auxiliar *auxs);
void criacaodeumcsv(struct auxiliar *auxs);
void leArquivocsv(struct gdpperc *pib);
void criarcsvfinal(struct gdpperc *pib);

int main (int argc , char *argv)
{
int qntda;
int qntd;
qntda = 189;
struct auxiliar *auxs = malloc (qntda * sizeof(struct auxiliar));
printf("informe a quantidade de paises que deseja usar: \n");
scanf("%d",&qntd);
struct gdpperc *pib = malloc (qntd * sizeof(struct gdpperc));
pib->qntd = qntd;
criacaodeumcsv(auxs);
criarcsvfinal(pib);
free(auxs);
system("PAUSE");
return 0;
}

void leArquivoum(struct auxiliar *auxs){
int i;
FILE *arquivoum;
arquivoum = fopen("C:\\Users\\John\\Desktop\\trabalho\\gdp.csv","r");
for (i=0; i< 189; i++)
{
    fscanf(arquivoum, "%[^;]", &auxs[i].paises);
    for(int j=0; j < 4; j++){
    fscanf(arquivoum, "%[^;]", &auxs[i].aux1);
    }
    fscanf(arquivoum, "%f[^;]", &auxs[i].gdp_perc);

}
  fclose(arquivoum);
}

void leArquivodois(struct auxiliar *auxs){

int k;

FILE *arquivo2;

arquivo2 = fopen("C:\\Users\\John\\Desktop\\trabalho\\qualidade.csv","r");
for(k = 0; k < 41; k++)
{
   for(int q=0;q<=1;q++)
   {
      fscanf(arquivo2, "%[^;]",&auxs[k].aux3);
   }
    fscanf(arquivo2, "%[^;]",&auxs[k].paisaux);
   for(int l=0; l<21; l++){
    fscanf(arquivo2, "%d[^;]",auxs[k].aux2);
    }
    for(int i=0; i < 189; i++ ){
        while (strcmp (auxs[k].paisaux,auxs[i].paises) == 0);
        {
        fscanf(arquivo2, "%f[^;]", &auxs[i].satisfacao);
        }
    }

}
  fclose(arquivo2);
}


void criacaodeumcsv(struct auxiliar *auxs){
int indice;
indice = 189;
FILE *arquivof;
arquivof = fopen("C:\\Users\\John\\Desktop\\trabalho\\primeiroresult.csv","w");
    fprintf(arquivof,"%d\n", &indice);
for(int i=0; i < 189; i++){
fprintf(arquivof, "%s,%f,%f\n", &auxs[i].paises,auxs[i].gdp_perc,auxs[i].satisfacao);
}
}

void leArquivocsv(struct gdpperc *pib)/* função para a abertura do arquivo csv. */{
int i;
    FILE *arquivofinal;
   arquivofinal = fopen("C:\\Users\\John\\Desktop\\trabalho\\primeiroresult.csv","r");
for (i=0; i < pib[i].qntd ; i++)
    {

        fscanf(arquivofinal, "%d[^,\n]", &pib[i].qntd);
        fscanf(arquivofinal, "%[^,]", &pib[i].pais);
        fscanf(arquivofinal, "%f[^,]", &pib[i].gdp);
        fscanf(arquivofinal, "%f[^,\n]", &pib[i].satisfacao_vidareal);

}
}
void criarcsvfinal(struct gdpperc *pib){
float teta0 = 2.5;
float teta1 = 1;
float n = 0.1;
float eam;
int i;
FILE *arquivofinale;
for (i=0; i < pib->qntd; i++ )
{
    arquivofinale = fopen("C:\\Users\\John\\Desktop\\trabalho\\resultadofinal.csv","w");
if (pib[i].satisfacao_vidareal != 0 ){
    for (int s = 0;s < 100;s++){
       pib[i].satisfcao_vidacalc = teta1 + teta0 * pib[i].gdp;
        pib[i].erro = pib[i].satisfcao_vidacalc - pib[i].satisfacao_vidareal;
        teta0 = teta0 + n * pib[i].erro * pib[i].gdp;
        teta1 = teta1 + n * pib[i].erro * pib[i].gdp;
    }
    }
eam = pib[i].satisfcao_vidacalc - pib[i].satisfacao_vidareal / pib[i].qntd;
    }
for (i=0; i < pib->qntd; i++ ){
    fprintf(arquivofinale,"%s, %f, %f, %f, %f \n",&pib[i].pais,pib[i].gdp,pib[i].satisfcao_vidacalc,pib[i].satisfacao_vidareal,pib[i].erro);
}
fprintf(arquivofinale, "Erro absoluto Médio: %f", &eam);
fclose(arquivofinale);
 }

Sabe me dizer se tem algo errado na leitura do csv?

Compartilhar este post


Link para o post
Compartilhar em outros sites
19 minutos atrás, johnkaos disse:

Sabe me dizer se tem algo errado na leitura do csv?

 

vou ler em seguida

 

Sobre os theta(i) parece ser uma interpolação linear em torno da série de gdp, mas os valôres de gdp(i) são independentes, mais precisamente GDP de países distintos. Consigo entender talvez a parte formal, mas como isso vai dar algo relevante eu tenho dúvidas... Num dado momento o GDP vai ser Bolivia/Botswana/Brazil/Brunei por exemplo e não entendo o que vai significar interpolar entre valores de GDP desses países. Claro, não pensei muito nisso...

adicionado 1 minuto depois
24 minutos atrás, johnkaos disse:

Sabe me dizer se tem algo errado na leitura do csv?

 

fala da função

 void leArquivocsv(struct gdpperc *pib)

?

Compartilhar este post


Link para o post
Compartilhar em outros sites

@arfneto eu achei o enunciado um poco confuso,faltou objetividade...então só fui seguindo o que ele pede...

até na hora de usar fprintf nos csv.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro 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 publicações 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...

 

javaweb-popup.jpg

CURSO ONLINE DE PROGRAMAÇÃO
FULL STACK

Entre para o mercado que paga mais de R$ 12.000 por mês e não tem crise!

CLIQUE AQUI E INSCREVA-SE AGORA MESMO!