Merge pull request #18 from axell-brendow/master
Adiciona questão "Registro em C" do TP2
This commit is contained in:
commit
052eb21b7a
|
|
@ -1,96 +0,0 @@
|
|||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.text.ParseException;
|
||||
|
||||
public class Template {
|
||||
|
||||
// funcao que simula um construtor
|
||||
public static Track cadastra(String dadosMusica) throws ParseException {
|
||||
String campos[] = new String[19];
|
||||
int j = 0;
|
||||
String temp = "";
|
||||
for (int i = 0; i < 19; i++) {
|
||||
temp = "";
|
||||
while (j < dadosMusica.length() && ((dadosMusica.charAt(j) != ',')
|
||||
|| !(dadosMusica.charAt(j) == ',' && dadosMusica.charAt(j + 1) != ' '))) {
|
||||
if (dadosMusica.charAt(j) != '"')
|
||||
temp += dadosMusica.charAt(j);
|
||||
j++;
|
||||
}
|
||||
j++;
|
||||
campos[i] = temp;
|
||||
}
|
||||
Track musica = new Track(campos);
|
||||
|
||||
return musica;
|
||||
}
|
||||
|
||||
/*
|
||||
* leitura das musicas e geracao dos objetos Track
|
||||
*/
|
||||
public static Track[] inserirPlaylist(int quantidade, String idList[], String totalMusicList[]) throws ParseException {
|
||||
Track musicas[] = new Track[quantidade];
|
||||
for (int i = 0; i < quantidade; i++) {
|
||||
for (int j = 0; j < totalMusicList.length; j++) {
|
||||
if (totalMusicList[j].contains(idList[i])) {
|
||||
String dadosMusic = totalMusicList[j];
|
||||
musicas[i] = cadastra(dadosMusic);
|
||||
j = totalMusicList.length;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return musicas;
|
||||
}
|
||||
|
||||
/*
|
||||
* leitura de todas as linhas da entrada padrao
|
||||
*/
|
||||
public static int entradaPadrao(String idList[]) throws IOException {
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
|
||||
int i = 0;
|
||||
// faco a leitura dos ids do pub.in
|
||||
String linha = in.readLine();
|
||||
while (!(linha.contains("FIM"))) {
|
||||
idList[i] = linha;
|
||||
i++;
|
||||
linha = in.readLine();
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* leitura de todas as musicas do arquivo de entrada /tmp/data.csv
|
||||
*/
|
||||
public static String[] ler() throws Exception {
|
||||
final int TOTAL_MUSIC_NUMBER = 170625;
|
||||
String totalMusicList[] = new String[TOTAL_MUSIC_NUMBER];
|
||||
FileReader arquivo = new FileReader("./tmp/data.csv");
|
||||
BufferedReader ler = new BufferedReader(arquivo);
|
||||
String linha = ler.readLine();
|
||||
linha = ler.readLine();
|
||||
int i = 0;
|
||||
while (linha != null) {
|
||||
totalMusicList[i] = linha;
|
||||
linha = ler.readLine();
|
||||
i++;
|
||||
}
|
||||
arquivo.close();
|
||||
return totalMusicList;
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
// vetor que armazena os ids da entrada padrao pub.in
|
||||
String idList[] = new String[500];
|
||||
int playlistTam = entradaPadrao(idList);
|
||||
// leitura de todas as musicas do arquivo de entrada /tmp/data.csv
|
||||
String totalMusicList[] = ler();
|
||||
Track musicas[] = inserirPlaylist(playlistTam, idList, totalMusicList);
|
||||
|
||||
for(Track musica:musicas)
|
||||
musica.imprimir();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,244 +0,0 @@
|
|||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
public class Track {
|
||||
|
||||
// (0)valence,(1)year,(2)acousticness,(3)artists,(4)danceability,(5)duration_ms,(6)energy,
|
||||
// (7)explicit,(8)id,(9)instrumentalness,(10)key,(11)liveness,(12)loudness,(13)mode,
|
||||
// (14)name,(15)popularity,(16)release_date,(17)speechiness,(18)tempo
|
||||
private String nome;
|
||||
private String id; // 8
|
||||
private String key; // 10
|
||||
private String artists; // 3
|
||||
private Date realease; // 16
|
||||
private double acousticness; // 2
|
||||
private double danceability; // 4
|
||||
private double energy; // 6
|
||||
private int duration; // 5
|
||||
private double instrumentalness; // 9
|
||||
private double valence; // 0
|
||||
private int popularity; // 15
|
||||
private float tempo; // 18
|
||||
private double liveness; // 11
|
||||
private double loudness; // 12
|
||||
private double speechiness; // 17
|
||||
private int year; // 1
|
||||
|
||||
public Track() {
|
||||
this.id = "";
|
||||
}
|
||||
|
||||
public Track(String[] values) throws ParseException {
|
||||
this.id = values[8]; // 8
|
||||
this.nome = values[14]; // 14
|
||||
this.key = values[10]; // 10
|
||||
this.acousticness = Double.parseDouble(values[2]); // 2
|
||||
this.danceability = Double.parseDouble(values[4]); // 4
|
||||
this.energy = Double.parseDouble(values[6]); // 6
|
||||
this.duration = Integer.parseInt(values[5]); // 5
|
||||
this.instrumentalness = Double.parseDouble(values[9]); // 9
|
||||
this.valence = Double.parseDouble(values[0]); // 0
|
||||
this.popularity = Integer.parseInt(values[15]); // 15
|
||||
this.tempo = Float.parseFloat(values[18]); // 18
|
||||
this.liveness = Double.parseDouble(values[11]); // 11
|
||||
this.loudness = Double.parseDouble(values[12]); // 12
|
||||
this.speechiness = Double.parseDouble(values[17]); // 17
|
||||
this.year = Integer.parseInt(values[1]); // 1
|
||||
|
||||
String artistsString = "";
|
||||
int i = 0;
|
||||
while (i < values[3].length()) {
|
||||
if (!(values[3].charAt(i) == 39 && (values[3].charAt(i - 1) == 91 ||
|
||||
values[3].charAt(i + 1) == 93 || values[3].charAt(i + 1) == 44 ||
|
||||
values[3].charAt(i - 2) == 44))) {
|
||||
artistsString += values[3].charAt(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
artists = artistsString; // 3 ;
|
||||
|
||||
SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd");
|
||||
if (values[16].length() == 4) {
|
||||
realease = formato.parse(values[16] + "-01-01");
|
||||
} else if (values[16].length() == 7) {
|
||||
realease = formato.parse(values[16] + "-01");
|
||||
} else {
|
||||
realease = formato.parse(values[16]);
|
||||
}
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getNome() {
|
||||
return nome;
|
||||
}
|
||||
|
||||
public void setName(String nome) {
|
||||
this.nome = nome;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getArtists() {
|
||||
return artists;
|
||||
}
|
||||
|
||||
public void setArtists(String artists) {
|
||||
this.artists = artists;
|
||||
}
|
||||
|
||||
public Date getRealease() {
|
||||
return realease;
|
||||
}
|
||||
|
||||
public void setRealease(Date realease) {
|
||||
this.realease = realease;
|
||||
}
|
||||
|
||||
public double getAcousticness() {
|
||||
return acousticness;
|
||||
}
|
||||
|
||||
public void setAcousticness(double acousticness) {
|
||||
this.acousticness = acousticness;
|
||||
}
|
||||
|
||||
public double getDanceability() {
|
||||
return danceability;
|
||||
}
|
||||
|
||||
public void setDanceability(double danceability) {
|
||||
this.danceability = danceability;
|
||||
}
|
||||
|
||||
public double getEnergy() {
|
||||
return energy;
|
||||
}
|
||||
|
||||
public void setEnergy(double energy) {
|
||||
this.energy = energy;
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(int duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public double getInstrumentalness() {
|
||||
return instrumentalness;
|
||||
}
|
||||
|
||||
public void setInstrumentalness(double instrumentalness) {
|
||||
this.instrumentalness = instrumentalness;
|
||||
}
|
||||
|
||||
public double getValence() {
|
||||
return valence;
|
||||
}
|
||||
|
||||
public void setValence(double valence) {
|
||||
this.valence = valence;
|
||||
}
|
||||
|
||||
public int getPopularity() {
|
||||
return popularity;
|
||||
}
|
||||
|
||||
public void setPopularity(int popularity) {
|
||||
this.popularity = popularity;
|
||||
}
|
||||
|
||||
public float getTempo() {
|
||||
return tempo;
|
||||
}
|
||||
|
||||
public void setTempo(float tempo) {
|
||||
this.tempo = tempo;
|
||||
}
|
||||
|
||||
public double getLiveness() {
|
||||
return liveness;
|
||||
}
|
||||
|
||||
public void setLiveness(double liveness) {
|
||||
this.liveness = liveness;
|
||||
}
|
||||
|
||||
public double getLoudness() {
|
||||
return loudness;
|
||||
}
|
||||
|
||||
public void setLoudness(double loudness) {
|
||||
this.loudness = loudness;
|
||||
}
|
||||
|
||||
public double getSpeechiness() {
|
||||
return speechiness;
|
||||
}
|
||||
|
||||
public void setSpeechiness(double speechiness) {
|
||||
this.speechiness = speechiness;
|
||||
}
|
||||
|
||||
public int getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
public void setYear(int year) {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
|
||||
public Track clone() {
|
||||
Track novo = new Track();
|
||||
novo.nome = this.nome;
|
||||
novo.id = this.id;
|
||||
novo.key = this.key;
|
||||
novo.artists = this.artists;
|
||||
novo.realease = this.realease;
|
||||
novo.acousticness = this.acousticness;
|
||||
novo.danceability = this.danceability;
|
||||
novo.energy = this.energy;
|
||||
novo.duration = this.duration;
|
||||
novo.instrumentalness = this.instrumentalness;
|
||||
novo.valence = this.valence;
|
||||
novo.popularity = this.popularity;
|
||||
novo.tempo = this.tempo;
|
||||
novo.liveness = this.liveness;
|
||||
novo.loudness = this.loudness;
|
||||
novo.speechiness = this.speechiness;
|
||||
novo.year = this.year;
|
||||
return novo;
|
||||
}
|
||||
|
||||
|
||||
public void imprimir() throws Exception {
|
||||
System.out.println(this.toString());
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
|
||||
return id + " ## " + artists.toString() + " ## " + nome + " ## " + sdf.format(realease) + " ## " + acousticness
|
||||
+ " ## " + danceability + " ## " + instrumentalness + " ## " + liveness + " ## " + loudness + " ## "
|
||||
+ speechiness + " ## " + energy + " ## " + duration;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,226 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define MAX_LINE_SIZE 860
|
||||
|
||||
typedef struct {
|
||||
char id[30];
|
||||
char name[200];
|
||||
char key[15];
|
||||
char artists[40][100];
|
||||
int num_artists;
|
||||
char release_date[12];
|
||||
double acousticness;
|
||||
double danceability;
|
||||
double energy;
|
||||
int duration_ms;
|
||||
double instrumentalness;
|
||||
double valence;
|
||||
int popularity;
|
||||
float tempo;
|
||||
double liveness;
|
||||
double loudness;
|
||||
double speechiness;
|
||||
int year;
|
||||
} Musica;
|
||||
|
||||
Musica clone_music(Musica *music) {
|
||||
return *music;
|
||||
}
|
||||
|
||||
char *remove_line_break(char line[]) {
|
||||
int size = strlen(line);
|
||||
|
||||
if (line[size - 2] == '\r')
|
||||
line[size - 2] = '\0';
|
||||
|
||||
else if (line[size - 1] == '\r' || line[size - 1] == '\n')
|
||||
line[size - 1] = '\0';
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
char *read_quotted_csv_field(char *field_ptr, char *output) {
|
||||
field_ptr++;
|
||||
while (*field_ptr != '\0') {
|
||||
if (*field_ptr == '"') {
|
||||
if (*(field_ptr + 1) == '"') {
|
||||
*output++ = '"';
|
||||
field_ptr += 2;
|
||||
} else {
|
||||
field_ptr++;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
*output++ = *field_ptr++;
|
||||
}
|
||||
}
|
||||
*output = '\0';
|
||||
return field_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lê uma única célula de um CSV.
|
||||
*
|
||||
* @param field_ptr Ponteiro para o primeiro caractere dessa célula.
|
||||
* @param output Arranjo que receberá o conteúdo da célula.
|
||||
*
|
||||
* @return Ponteiro que aponta para uma posição depois da célula.
|
||||
* Geralmente um ponteiro para uma vírgula ou o fim da linha.
|
||||
*/
|
||||
char *read_csv_field(char *field_ptr, char *output) {
|
||||
if (*field_ptr == '"') return read_quotted_csv_field(field_ptr, output);
|
||||
|
||||
while (*field_ptr != '\0' && *field_ptr != ',') *output++ = *field_ptr++;
|
||||
|
||||
*output = '\0';
|
||||
return field_ptr;
|
||||
}
|
||||
|
||||
char *read_artist(char *output, char *artist_ptr) {
|
||||
char delimiter = *artist_ptr++;
|
||||
|
||||
while (*artist_ptr != delimiter) {
|
||||
if (*artist_ptr == '\\') *output++ = *artist_ptr++;
|
||||
*output++ = *artist_ptr++;
|
||||
}
|
||||
|
||||
*output = '\0';
|
||||
return artist_ptr + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lê o campo artists de uma música e preenche o arranjo de artistas dela.
|
||||
*
|
||||
* @param music Ponteiro para a struct da música.
|
||||
* @param artists_field Ponteiro para o primeiro caractere do campo artists.
|
||||
* Um colchete '[' em todos os casos.
|
||||
*/
|
||||
void read_artists(Musica *music, char *artists_field) {
|
||||
artists_field++;
|
||||
int i = 0;
|
||||
while (1) {
|
||||
artists_field = read_artist(music->artists[i++], artists_field);
|
||||
if (*artists_field == ']') break;
|
||||
artists_field += 2;
|
||||
}
|
||||
music->num_artists = i;
|
||||
}
|
||||
|
||||
void read_release_date(Musica *music, char field[]) {
|
||||
strcpy(music->release_date, field);
|
||||
if (strlen(music->release_date) == 4) strcat(music->release_date, "/01/01");
|
||||
music->release_date[4] = '/';
|
||||
music->release_date[7] = '/';
|
||||
}
|
||||
|
||||
double handle_percentage(double value) {
|
||||
return ceil(value) == value ? value / 100 : value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lê uma linha vinda do CSV e preenche os campos da Música.
|
||||
*
|
||||
* @param music Ponteiro para a struct da música.
|
||||
* @param line Linha do CSV.
|
||||
*
|
||||
* Ex.: read_music(&music, "0.598,2018,0.136,\"['Royce Da 5\\'9""', 'Eminem', 'King Green']\",0.706,283077,0.745,1,6LZe8JfVaqcpq8yjkHtWQe,0.0,10,0.268,-5.97,0,Caterpillar (feat. Eminem & King Green),61,2018-05-04,0.441,91.08")
|
||||
*/
|
||||
void read_music(Musica *music, char line[]) {
|
||||
char field[MAX_LINE_SIZE];
|
||||
remove_line_break(line);
|
||||
|
||||
line = read_csv_field(line, field);
|
||||
music->valence = handle_percentage(atof(field));
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
music->year = atoi(field);
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
music->acousticness = handle_percentage(atof(field));
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
read_artists(music, field);
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
music->danceability = handle_percentage(atof(field));
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
music->duration_ms = atoi(field);
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
music->energy = handle_percentage(atof(field));
|
||||
|
||||
line = read_csv_field(line + 1, field); // Skip 'explicit' column
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
strcpy(music->id, field);
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
music->instrumentalness = handle_percentage(atof(field));
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
strcpy(music->key, field);
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
music->liveness = handle_percentage(atof(field));
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
music->loudness = atof(field);
|
||||
|
||||
line = read_csv_field(line + 1, field); // Skip 'mode' column
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
strcpy(music->name, field);
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
music->popularity = atoi(field);
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
read_release_date(music, field);
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
music->speechiness = handle_percentage(atof(field));
|
||||
|
||||
line = read_csv_field(line + 1, field);
|
||||
music->tempo = atof(field);
|
||||
}
|
||||
|
||||
void print_artists(Musica *music) {
|
||||
printf("[");
|
||||
|
||||
if (music->num_artists > 0) {
|
||||
printf("%s", music->artists[0]);
|
||||
|
||||
for (int i = 1; i < music->num_artists; i++)
|
||||
printf(", %s", music->artists[i]);
|
||||
}
|
||||
|
||||
printf("]");
|
||||
}
|
||||
|
||||
void print_music(Musica *music) {
|
||||
printf("%s ## ", music->id);
|
||||
print_artists(music);
|
||||
printf(" ## %s ## %c%c/%c%c/%c%c%c%c ## %G ## %G ## %G ## %G ## %G ## %G ## %G ## %d\n",
|
||||
music->name,
|
||||
music->release_date[8],
|
||||
music->release_date[9],
|
||||
music->release_date[5],
|
||||
music->release_date[6],
|
||||
music->release_date[0],
|
||||
music->release_date[1],
|
||||
music->release_date[2],
|
||||
music->release_date[3],
|
||||
music->acousticness,
|
||||
music->danceability,
|
||||
music->instrumentalness,
|
||||
music->liveness,
|
||||
music->loudness,
|
||||
music->speechiness,
|
||||
music->energy,
|
||||
music->duration_ms
|
||||
);
|
||||
}
|
||||
|
|
@ -1,230 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TOTAL_MUSIC_NUMBER 170625
|
||||
#define MAX_LINE_LENGTH 1000
|
||||
#define MAX_PLAYLIST_LENGTH 500
|
||||
#define MAX_ID_LENGTH 25
|
||||
|
||||
typedef struct{
|
||||
char list[500];
|
||||
int list_length;
|
||||
}Artists_list;
|
||||
|
||||
//struct Date
|
||||
typedef struct{
|
||||
int day;
|
||||
int month;
|
||||
int year;
|
||||
}Date;
|
||||
|
||||
//struct Music
|
||||
typedef struct{
|
||||
char id[MAX_ID_LENGTH];
|
||||
char name[200];
|
||||
char key[200];
|
||||
Artists_list artists;
|
||||
Date release_date;
|
||||
double acousticness;
|
||||
double danceability;
|
||||
double energy;
|
||||
int duration_ms;
|
||||
double instrumentalness;
|
||||
double valence;
|
||||
int popularity;
|
||||
float tempo;
|
||||
double liveness;
|
||||
double loudness;
|
||||
double speechiness;
|
||||
int year;
|
||||
}Music;
|
||||
|
||||
//display que adequa a formatacao de datas
|
||||
void displayFormattedDate(Date *d){
|
||||
printf("%0*d/%0*d/%0*d", 2, d->day, 2, d->month, 4, d->year);
|
||||
}
|
||||
|
||||
//ler todo o arquivo
|
||||
void ler(char* filepath,char** totalMusicList){
|
||||
FILE *f = fopen(filepath,"r");
|
||||
|
||||
if(f == NULL){
|
||||
perror("Error opening file"); //checagem de erro ao abrir o arquivo
|
||||
printf("\n Sorry:(\n ");
|
||||
}
|
||||
|
||||
else {
|
||||
int i = 0;
|
||||
char aux[MAX_LINE_LENGTH];
|
||||
fgets(aux, MAX_LINE_LENGTH, f);
|
||||
while(fgets(aux, MAX_LINE_LENGTH, f) != NULL){
|
||||
strcpy(totalMusicList[i], aux);
|
||||
i++;
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
//impressao padrao dos elementos relevantes da classe
|
||||
void imprimir(Music *m){
|
||||
printf("%s ## %s ## %s ## ", m->id, m->artists.list, m->name);
|
||||
displayFormattedDate(&m->release_date);
|
||||
printf(" ## %lg ## %lg ## %lg ## %lg ",m->acousticness, m->danceability, m->instrumentalness, m->liveness);
|
||||
printf("## %lg ## %lg ## %lg ## %d\n", m->loudness, m->speechiness, m->energy, m->duration_ms);
|
||||
}
|
||||
|
||||
//imprimir na tela
|
||||
void displayPlaylist(Music playlist[], int n){
|
||||
for (int i = 0; i < n; i++)
|
||||
imprimir(&playlist[i]);
|
||||
}
|
||||
|
||||
//funcao de entrada de dados padronizada
|
||||
int standartInput(char inputs[MAX_PLAYLIST_LENGTH][MAX_ID_LENGTH]){
|
||||
char aux[MAX_ID_LENGTH];
|
||||
int input_quantity = 0;
|
||||
do{
|
||||
scanf(" %s", aux);
|
||||
if(strcmp(aux, "FIM")!= 0){
|
||||
strcpy(inputs[input_quantity], aux);
|
||||
input_quantity++;
|
||||
}
|
||||
}while(strcmp(aux, "FIM") != 0 && input_quantity <= MAX_PLAYLIST_LENGTH);
|
||||
return input_quantity;
|
||||
}
|
||||
|
||||
//pesquisa sequencial do cadastro
|
||||
void searchById(char id[MAX_ID_LENGTH], char **totalMusicList, char* resp){
|
||||
for(int i = 0; i < TOTAL_MUSIC_NUMBER; i++){
|
||||
if(strstr(totalMusicList[i], id) != NULL){
|
||||
strcpy(resp, totalMusicList[i]);
|
||||
i = TOTAL_MUSIC_NUMBER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//funcao que faz o split dos artibutos corretamente
|
||||
void readAtribute(int *stringIndex, char *infos, char* output){
|
||||
int i = *stringIndex;
|
||||
int j = 0;
|
||||
while(infos[i] != '\0' && ((infos[i] != ',') || !(infos[i] == ',' && infos[i + 1] != ' '))){ //pulamos virgulas e quotes desnecessarios
|
||||
if(infos[i] != '"')
|
||||
output[j++] = infos[i];
|
||||
i++;
|
||||
}
|
||||
output[j] = '\0';
|
||||
*stringIndex = ++i;
|
||||
}
|
||||
|
||||
//funcoes referente a manipulacao de datas aaaa-mm-dd
|
||||
void insertDate(Date* d, char* not_formatted_date){
|
||||
char day[3];
|
||||
char month[3];
|
||||
char year[5];
|
||||
|
||||
strncpy(year,not_formatted_date,4);
|
||||
d->year = atoi(year);
|
||||
|
||||
if(not_formatted_date[4] != '-'){
|
||||
strcpy(month,"01");
|
||||
}
|
||||
|
||||
else{
|
||||
month[0] = not_formatted_date[5];
|
||||
month[1] = not_formatted_date[6];
|
||||
}
|
||||
|
||||
if(not_formatted_date[7] != '-'){
|
||||
strcpy(day,"01");
|
||||
}
|
||||
else {
|
||||
day[0] = not_formatted_date[8];
|
||||
day[1] = not_formatted_date[9];
|
||||
}
|
||||
d->month = atof(month);
|
||||
d->year = atof(year);
|
||||
d->day = atof(day);
|
||||
}
|
||||
|
||||
//leitura dos artistas
|
||||
void insertArtists(Artists_list* a,char* input){
|
||||
int i = 0;
|
||||
a->list_length = 0;
|
||||
while(i < strlen(input)){
|
||||
if(!(input[i] == 39 && (input[i - 1] == 91 || input[i+1] == 93 || input[i + 1] == 44 || input[i - 2] == 44))){
|
||||
a->list[a->list_length] = input[i];
|
||||
a->list_length++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
//funcao que simula um construtor
|
||||
void cadastra(char *music_info, Music *m){
|
||||
int lineIndex = 0;
|
||||
char fields[19][MAX_LINE_LENGTH];
|
||||
|
||||
//split dos atributos
|
||||
for (int i = 0; i < 19; i++)
|
||||
readAtribute(&lineIndex, music_info, fields[i]);
|
||||
|
||||
//cadastro individual
|
||||
m->valence = atof(fields[0]);
|
||||
m->year = atoi(fields[1]);
|
||||
m->acousticness = atof(fields[2]);
|
||||
insertArtists(&m->artists, fields[3]);
|
||||
m->danceability = atof(fields[4]);
|
||||
m->duration_ms = atof(fields[5]);
|
||||
m->energy = atof(fields[6]);
|
||||
//explicit nao utilizado
|
||||
strcpy(m->id, fields[8]);
|
||||
m->instrumentalness = atof(fields[9]);
|
||||
strcpy(m->key, fields[10]);
|
||||
m->liveness = atof(fields[11]);
|
||||
m->loudness = atof(fields[12]);
|
||||
//mode nao utilizado
|
||||
strcpy(m->name, fields[14]);
|
||||
m->popularity = atoi(fields[15]);
|
||||
insertDate(&m->release_date, fields[16]);
|
||||
m->speechiness = atof(fields[17]);
|
||||
m->tempo = atof(fields[18]);
|
||||
}
|
||||
|
||||
void insertOnPlaylist(int insert_quantity, char idList[MAX_PLAYLIST_LENGTH][MAX_ID_LENGTH], char **totalMusicList, Music playlist[]){
|
||||
for (int i = 0; i < insert_quantity; i++)
|
||||
{
|
||||
char music_data[MAX_LINE_LENGTH];
|
||||
searchById(idList[i], totalMusicList, music_data);
|
||||
cadastra(music_data, &playlist[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
//vetor que armazena os ids do input
|
||||
char idList[MAX_PLAYLIST_LENGTH][MAX_ID_LENGTH];
|
||||
// musicas que serao lidas pelo pub.in
|
||||
Music playlist[MAX_PLAYLIST_LENGTH];
|
||||
// numero de musicas de entrada
|
||||
int playlist_length;
|
||||
|
||||
//alocacao do array de strings
|
||||
char **totalMusicList;
|
||||
totalMusicList = (char **)malloc(sizeof(char *) * TOTAL_MUSIC_NUMBER);
|
||||
|
||||
//alocacao das strings contidas no array
|
||||
for (int i = 0; i < TOTAL_MUSIC_NUMBER; i++)
|
||||
totalMusicList[i] = (char *)malloc(sizeof(char *) * MAX_LINE_LENGTH);
|
||||
|
||||
ler("/tmp/data.csv", totalMusicList);
|
||||
|
||||
playlist_length = standartInput(idList);
|
||||
|
||||
insertOnPlaylist(playlist_length, idList, totalMusicList, playlist);
|
||||
|
||||
displayPlaylist(playlist, playlist_length);
|
||||
|
||||
free(totalMusicList);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_FIELD_SIZE 100
|
||||
|
||||
typedef struct {
|
||||
char nome[MAX_FIELD_SIZE];
|
||||
char formato[MAX_FIELD_SIZE];
|
||||
char duracao[MAX_FIELD_SIZE];
|
||||
char pais[MAX_FIELD_SIZE];
|
||||
char idioma[MAX_FIELD_SIZE];
|
||||
char emissora[MAX_FIELD_SIZE];
|
||||
char transmissao[MAX_FIELD_SIZE];
|
||||
int num_temporadas;
|
||||
int num_episodios;
|
||||
} Serie;
|
||||
|
||||
char *remove_line_break(char *line) {
|
||||
while (*line != '\r' && *line != '\n') line++;
|
||||
*line = '\0';
|
||||
return line;
|
||||
}
|
||||
|
||||
char *freadline(char *line, int max_size, FILE *file) {
|
||||
return remove_line_break(fgets(line, max_size, file));
|
||||
}
|
||||
|
||||
char *readline(char *line, int max_size) {
|
||||
return freadline(line, max_size, stdin);
|
||||
}
|
||||
|
||||
void print_serie(Serie *serie) {
|
||||
printf("%s %s %s %s %s %s %s %d %d\n",
|
||||
serie->nome,
|
||||
serie->formato,
|
||||
serie->duracao,
|
||||
serie->pais,
|
||||
serie->idioma,
|
||||
serie->emissora,
|
||||
serie->transmissao,
|
||||
serie->num_temporadas,
|
||||
serie->num_episodios
|
||||
);
|
||||
}
|
||||
|
||||
// Retorna o tamanho em bytes de um arquivo.
|
||||
long tam_arquivo(FILE *file) {
|
||||
fseek(file, 0L, SEEK_END);
|
||||
long size = ftell(file);
|
||||
rewind(file);
|
||||
return size;
|
||||
}
|
||||
|
||||
// Retorna todo o conteúdo do arquivo numa string.
|
||||
char *ler_html(char filename[]) {
|
||||
FILE *file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Falha ao abrir arquivo %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
long tam = tam_arquivo(file);
|
||||
char *html = (char *) malloc(sizeof(char) * (tam + 1));
|
||||
fread(html, 1, tam, file);
|
||||
fclose(file);
|
||||
html[tam] = '\0';
|
||||
return html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Extrai os textos de uma tag html.
|
||||
*
|
||||
* @param html Ponteiro para o caractere que abre a tag '<'.
|
||||
* @param texto Ponteiro para onde o texto deve ser colocado.
|
||||
*
|
||||
* @return Ponteiro para o texto extraído.
|
||||
*/
|
||||
char *extrair_texto(char *html, char *texto) {
|
||||
char *start = texto;
|
||||
int contagem = 0;
|
||||
while (*html != '\0') {
|
||||
if (*html == '<') {
|
||||
if (
|
||||
(*(html + 1) == 'p') ||
|
||||
(*(html + 1) == 'b' && *(html + 2) == 'r') ||
|
||||
(*(html + 1) == '/' && *(html + 2) == 'h' && *(html + 3) == '1') ||
|
||||
(*(html + 1) == '/' && *(html + 2) == 't' && *(html + 3) == 'h') ||
|
||||
(*(html + 1) == '/' && *(html + 2) == 't' && *(html + 3) == 'd')
|
||||
) break;
|
||||
else contagem++;
|
||||
}
|
||||
else if (*html == '>') contagem--;
|
||||
else if (contagem == 0 && *html != '"') {
|
||||
if (*html == '&') html = strchr(html, ';');
|
||||
else if (*html != '\r' && *html != '\n') *texto++ = *html;
|
||||
}
|
||||
html++;
|
||||
}
|
||||
*texto = '\0';
|
||||
return *start == ' ' ? start + 1 : start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lê o HTML da série e popula os campos da struct.
|
||||
*
|
||||
* @param serie Struct Serie que vai receber os dados.
|
||||
* @param html String contendo todo o HTML do arquivo.
|
||||
*/
|
||||
void ler_serie(Serie *serie, char *html) {
|
||||
char texto[MAX_FIELD_SIZE];
|
||||
|
||||
char *ptr = strstr(html, "<h1");
|
||||
extrair_texto(ptr, texto);
|
||||
|
||||
char *parenteses_ptr = strchr(texto, '(');
|
||||
if (parenteses_ptr != NULL) *(parenteses_ptr - 1) = '\0';
|
||||
|
||||
strcpy(serie->nome, texto);
|
||||
|
||||
ptr = strstr(ptr, "<table class=\"infobox_v2\"");
|
||||
|
||||
ptr = strstr(ptr, "Formato");
|
||||
ptr = strstr(ptr, "<td");
|
||||
strcpy(serie->formato, extrair_texto(ptr, texto));
|
||||
|
||||
ptr = strstr(ptr, "Duração");
|
||||
ptr = strstr(ptr, "<td");
|
||||
strcpy(serie->duracao, extrair_texto(ptr, texto));
|
||||
|
||||
ptr = strstr(ptr, "País de origem");
|
||||
ptr = strstr(ptr, "<td");
|
||||
strcpy(serie->pais, extrair_texto(ptr, texto));
|
||||
|
||||
ptr = strstr(ptr, "Idioma original");
|
||||
ptr = strstr(ptr, "<td");
|
||||
strcpy(serie->idioma, extrair_texto(ptr, texto));
|
||||
|
||||
ptr = strstr(ptr, "Emissora de televisão original");
|
||||
ptr = strstr(ptr, "<td");
|
||||
strcpy(serie->emissora, extrair_texto(ptr, texto));
|
||||
|
||||
ptr = strstr(ptr, "Transmissão original");
|
||||
ptr = strstr(ptr, "<td");
|
||||
strcpy(serie->transmissao, extrair_texto(ptr, texto));
|
||||
|
||||
ptr = strstr(ptr, "N.º de temporadas");
|
||||
ptr = strstr(ptr, "<td");
|
||||
sscanf(extrair_texto(ptr, texto), "%d", &serie->num_temporadas);
|
||||
|
||||
ptr = strstr(ptr, "N.º de episódios");
|
||||
ptr = strstr(ptr, "<td");
|
||||
sscanf(extrair_texto(ptr, texto), "%d", &serie->num_episodios);
|
||||
}
|
||||
|
||||
#define MAX_LINE_SIZE 250
|
||||
#define PREFIXO "/tmp/series/"
|
||||
// #define PREFIXO "../entrada e saida/tp02/series/"
|
||||
|
||||
int isFim(char line[]) {
|
||||
return line[0] == 'F' && line[1] == 'I' && line[2] == 'M';
|
||||
}
|
||||
|
||||
int main() {
|
||||
Serie serie;
|
||||
size_t tam_prefixo = strlen(PREFIXO);
|
||||
char line[MAX_LINE_SIZE];
|
||||
|
||||
strcpy(line, PREFIXO);
|
||||
readline(line + tam_prefixo, MAX_LINE_SIZE);
|
||||
|
||||
while (!isFim(line + tam_prefixo)) {
|
||||
char *html = ler_html(line);
|
||||
ler_serie(&serie, html);
|
||||
free(html);
|
||||
print_serie(&serie);
|
||||
readline(line + tam_prefixo, MAX_LINE_SIZE);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Loading…
Reference in New Issue