C++ help

Status
Not open for further replies.

GhettoBusta

Legacy Member
Anyone good enough in C++ to help me out with this?
The lines I put in red are where the problem seems to be

Code:
#include <iostream>
#include <fstream>
#include <string>

struct type_chanson {
	char titre[31], artiste[31], album[31], commentaires[31], annee[5];
	int genre, identificateur;
};

using namespace std;

int EnTete(int noIdentificateur)
{
	string titre = "", artiste = "", album = "", annee = "", commentaires = "";
	ofstream F_sortie;
	F_sortie.open("listemp3.bin", ios::out | ios::binary);
	
	if (F_sortie.fail()) {
		cout << "Impossible d'ouvrir le fichier" << endl;
	}
	else
	{	
		type_chanson Nouveau;
		Nouveau.identificateur = noIdentificateur;

		cout << "Veuillez entrer le titre de la chanson" << endl;
[COLOR="Red"]		getline(cin, titre);
		for (unsigned int i = 1; i <= 29; i++) {
			Nouveau.titre[i] = titre[i];
		}[/COLOR]
		cout << "Veuillez entrer l'artiste de la chanson" << endl;
		cin >> Nouveau.artiste;
		cout << "Veuillez entrer l'album sur lequel se retrouve chanson" << endl;
		cin >> Nouveau.album;
		cout << "Veuillez entrer l'annee de parution de la chanson" << endl;
		cin >> Nouveau.annee;
		cout << "Veuillez entrer les commentaires qui portent sur la chanson" << endl;
		cin >> Nouveau.commentaires;
		cout << "Veuillez entrer le genre de la chanson" << endl;
		cin >> Nouveau.genre;
		cout << endl;

		F_sortie.seekp(0,ios::end);
		F_sortie.write((char*)&Nouveau, sizeof(type_chanson));
	}
	
	F_sortie.close();
	return(0);
}

int AfficheEnTete()
{
	return(0);
}


void main(void)
{
	int choix = 0, noIdentificateur = 0;

	do
	{
		cout << "Quelle operation desirez-vous effectuer? " << endl;
		cout << " 1. Entrer l'en-tete d'un fichier audio " << endl;
		cout << " 2. Afficher toutes les en-tetes que contient la base de donnee " << endl;
		cout << " 3. Afficher le nombre de fichiers audio d'un genre donne " << endl;
		cout << " 4. Afficher l'en-tete d'un fichier audio a partir de son no. d'identification " << endl;
		cout << " 5. Quitter " << endl;
		cout << "Selection : ";
		cin >> choix;
		cout << endl;

		switch(choix)
		{
		case 1 : 
			noIdentificateur++;
			EnTete(noIdentificateur);
			break;
		case 2 : 
			AfficheEnTete();
			break;
		case 3 : 
			break;
		case 4 : 
			break;
		default:
			break;
		}

	}
	while(5 != choix);
}
This is suppose to write in the string "titre", whatever the user enters. Then, with a loop, the string is transferred to characters (Nouveau.titre) ... which comes from:

struct type_chanson {
char titre[31], artiste[31], album[31], commentaires[31], annee[5];
int genre, identificateur;
};

type_chanson Nouveau;
Nouveau.identificateur = noIdentificateur;

I have two ideas:
-Either I am not accessing each character of the "titre" string right (titre is maybe not the good way)
-Either I can't use: Nouveau.titre... but then, how would I access each character in Nouveau.titre
 
Sorry, I'm not good enough in programmation ...

What are you studying in ??

I'm in TSO (technique systèmes ordinés) and we do this kind of stuff in one of my courses !
 
C'est peut-etre parce que ta loop tu la fais jusqu'a 29..

Si le titre est moins long, il arrive quoi ? Si le dernier caractere est pas \0 il arrive quoi ?

Tu devrais verifier la longueur de ta string avant de passer les caracteres dans une loop.

Je sais pas si ca peut t'aider

PS: NE declare jamais un main() en tant que void..
Le standard, c'est int main(void) ou int main(int argc, char **argv)

ps: J'comprends pas trop les cit,etc.. mais j'ai quand-meme une bonne idee J'prefere le c au c++
 
Humm, why dont you be consistent and stick to with stl::string in your type_chanson struct? I dont see the point of using a char array...
Then you could skip your loop and go like this:
Nouveau.titre = titre;

And why are you using a loop? you should go with something like this (if you want to keep your char array):
strcpy(Nouveau.titre, titre.c_str); (stl::string.c_str gives you a null terminated string, check docs)

School work I guess?
 
Humm, why dont you be consistent and stick to with stl::string in your type_chanson struct? I dont see the point of using a char array...
Then you could skip your loop and go like this:
Nouveau.titre = titre;

And why are you using a loop? you should go with something like this (if you want to keep your char array):
strcpy(Nouveau.titre, titre.c_str); (stl::string.c_str gives you a null terminated string, check docs)

School work I guess?
Yeah, but I should know all that. How do I put a stl::string in my type_chanson struct?
 
Yeah, but I should know all that. How do I put a stl::string in my type_chanson struct?

Sorry I meant std::string

Note that you are using "using namespace std;" so you can call string, instead of std::string for your type.

declare your struct like this:
struct type_chanson {
string titre, artiste, album, commentaires;
char annee[5];
int genre, identificateur;
};

Understand what you are working with... declaring an array of char (char myVar[31]) is simply allocating a block of 31 characters. So you are stuck with 31 characters.
Your input to the user is not limited to 31 characters. This is bypassed by using a string. The string is a bit more inteligent and will allocate size as needed. This is why you are using it with your getline (I assume this code was half written and given to you, right?)

getline, cin, std:string are all part of the Standard librairy. They work well together and are easy to use. Why bother with char array?

However I dont see why your current code doesnt work... other then the bad practices and accessing un-allocated memory (loop to 29, why 29 n e way?). What error do you get?
 
Sorry I meant std::string

Note that you are using "using namespace std;" so you can call string, instead of std::string for your type.

declare your struct like this:
struct type_chanson {
string titre, artiste, album, commentaires;
char annee[5];
int genre, identificateur;
};

Understand what you are working with... declaring an array of char (char myVar[31]) is simply allocating a block of 31 characters. So you are stuck with 31 characters.
Your input to the user is not limited to 31 characters. This is bypassed by using a string. The string is a bit more inteligent and will allocate size as needed. This is why you are using it with your getline (I assume this code was half written and given to you, right?)

getline, cin, std:string are all part of the Standard librairy. They work well together and are easy to use. Why bother with char array?

However I dont see why your current code doesnt work... other then the bad practices and accessing un-allocated memory (loop to 29, why 29 n e way?). What error do you get?
The things is, I need to limit the user to 30 characters. I am making a program that works with ID3v1 headers (mp3 headers). Unless there is a way to limit strings to 30 characters... is there?
 
The things is, I need to limit the user to 30 characters. I am making a program that works with ID3v1 headers (mp3 headers). Unless there is a way to limit strings to 30 characters... is there?

Blehh!
Anyone programming for ID3v1 tags instead of ID3v2 should be hit on the fingers with the keyboard. Repeatedly.

Same goes for people programming in coutry specific code page instead of Unicode. Their computers should be taken away. Happens with Russian programs all the time. They expect you to have Russian Windows which I will never ever install.
 
Blehh!
Anyone programming for ID3v1 tags instead of ID3v2 should be hit on the fingers with the keyboard. Repeatedly.

Same goes for people programming in coutry specific code page instead of Unicode. Their computers should be taken away. Happens with Russian programs all the time. They expect you to have Russian Windows which I will never ever install.
Like JSMeloche guessed... it's homework. Teacher says ID3v1, I do ID3v1. When teacher will ask ID3v2, I will use ID3v2.

Well... I got things sorted out and my program works like a charm, here is what I have for those that might be interested:
Code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

struct type_chanson {		//Declaration global de l'en-tete
	char titre[31], artiste[31], album[31], commentaires[31], annee[5];
	int genre, identificateur;
};
string leGenre[80] = {"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Mediative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock"};

void EntrerEnTete()		//Fonction qui permet d'entrer une nouvelle en-tete
{
	string titre = "", artiste = "", album = "", annee = "", commentaires = "", genre = "";		//Declaration des chaines de caracteres qui seront transferees aux elements de l'en-tete
	int nbElements;		//Declaration de la variable qui contiendra le nombre d'en-tetes deja inscrites dans le fichier binaire

	ofstream F_sortie;		//Fichier en lecture
	F_sortie.open("listemp3.bin", ios::binary|ios::out|ios::app);		//Ouverture du fichier en lecture

	if (F_sortie.fail()) {		//Verifie s'il y a erreur lors de l'ouverture du fichier
		cout << "Impossible d'ouvrir le fichier" << endl;
	}
	else
	{	
		cin.ignore(1);		//Sert a ignorer le retour chariot qui a mene a cette fonction
		type_chanson Nouveau;		//Declaration d'une variable de type type_chanson

		F_sortie.seekp(0, ios::end);		//Positionne le curseur a la fin du fichier binaire
		nbElements = F_sortie.tellp() / sizeof(type_chanson);		//Compte le nombre d'en-tetes deja presentes dans le fichier binaire
		Nouveau.identificateur = nbElements + 1;		//Inscris le nombre d'en-tetes deja presentes dans Nouveau

		cout << "Veuillez entrer le titre de la chanson" << endl;		//Demande a l'utilisateur d'entrer un titre de chanson
		getline(cin, titre);		//Inscris le titre entre par l'utilisateur dans une chaine de caracteres
		if (titre.size() > 30) {		//Reduit la taille de la chaine de caracteres si celle-ci est trop grande
			titre.resize(30);
		}
		strncpy_s(Nouveau.titre, titre.c_str(), 30);		//Copie la chaine de caracteres titre dans Nouveau
		cout << "Veuillez entrer l'artiste de la chanson" << endl;		//Demande a l'utilisateur d'entrer l'artiste de la chanson
		getline(cin, artiste);		//Inscris l'artiste entre par l'utilisateur dans une chaine de caracteres
		if (artiste.size() > 30) {		//Reduit la taille de la chaine de caracteres si celle-ci est trop grande
			artiste.resize(30);
		}
		strncpy_s(Nouveau.artiste, artiste.c_str(), 30);		//Copie la chaine de caracteres artiste dans Nouveau
		cout << "Veuillez entrer l'album sur lequel se retrouve chanson" << endl;		//Demande a l'utilisateur d'entrer l'album de la chanson
		getline(cin, album);		//Inscris l'album entre par l'utilisateur dans une chaine de caracteres
		if (album.size() > 30) {		//Reduit la taille de la chaine de caracteres si celle-ci est trop grande
			album.resize(30);
		}
		strncpy_s(Nouveau.album, album.c_str(), 30);		//Copie la chaine de caracteres album dans Nouveau
		cout << "Veuillez entrer l'annee de parution de l'album" << endl;		//Demande a l'utilisateur d'entrer l'annee de parution de l'album
		getline(cin, annee);		//Inscris l'annee de parution entre par l'utilisateur dans une chaine de caracteres
		if (annee.size() > 4) {		//Reduit la taille de la chaine de caracteres si celle-ci est trop grande
			titre.resize(4);
		}
		strncpy_s(Nouveau.annee, annee.c_str(), 4);		//Copie la chaine de caracteres annee dans Nouveau
		cout << "Veuillez entrer les commentaires qui portent sur la chanson" << endl;		//Demande a l'utilisateur d'entrer les commentaires qui portent sur la chanson
		getline(cin, commentaires);		//Inscris les commentaires entres par l'utilisateur dans une chaine de caracteres
		if (commentaires.size() > 30) {		//Reduit la taille de la chaine de caracteres si celle-ci est trop grande
			commentaires.resize(30);
		}
		strncpy_s(Nouveau.commentaires, commentaires.c_str(), 30);		//Copie la chaine de caracteres commentaires dans Nouveau
		cout << "Veuillez entrer le genre de la chanson: " << endl << "ATTENTION: Vous DEVEZ ecrire le genre de cette chanson de la MEME facon qu'il apparait dans la liste de genre des en-tetes ID3v1. Autrement, le genre sera 'Other' par defaut):" << endl;		//Demande a l'utilisateur d'entrer le genre de la chanson
		getline(cin, genre);		//Inscris le genre entre par l'utilisateur dans une chaine de caracteres
		Nouveau.genre = 12;		//Assigne le genre par defaut
		for (unsigned int i = 0; i < 80; i++) {		//Verifie si le genre entre par l'utilisateur correspond a un des 80 genres de la liste
			if (genre == leGenre[i]) {
				Nouveau.genre = i;		//Si oui, le numero correspondant au genre entre est inscris dans Nouveau
			}
		}
		F_sortie.write((char *) &Nouveau, sizeof(type_chanson));		//Ecrit la nouvelle en-tete dans le fichier binaire
	}
	
	cout << endl;
	F_sortie.close();		//Fermeture du fichier
}

void AfficheEnTete()		//Fonction qui affiche toutes les en-tetes inscrites dans le fichier binaire
{
	fstream F_entree;		//Fichier en ecriture et lecture
	F_entree.open("listemp3.bin", ios::binary|ios::out|ios::in);		//Ouverture du fichier en ecriture et lecture
	
	if (F_entree.fail()) {		//Verifie s'il y a erreur lors de l'ouverture du fichier
		cout << "Impossible d'ouvrir le fichier" << endl;
	}
	else
	{
		int nbElements;		//Declaration de la variable qui contiendra le nombre d'en-tetes deja inscrites dans le fichier binaire
		type_chanson Chanson;		//Declaration d'une variable de type type_chanson

		F_entree.seekg(0, ios::end);		//Positionne le curseur a la fin du fichier binaire
		nbElements = F_entree.tellg() / sizeof(type_chanson);		//Compte le nombre d'en-tetes presentes dans le fichier binaire

		F_entree.seekg(0, ios::beg);		//Positionne le cureuse au debut du fichier binaire
		for (unsigned int i = 0; i < nbElements; i++) {		//Pour chaque en-tete presente dans le fichier
			F_entree.read((char*)&Chanson, sizeof(type_chanson));		//Lecture de l'en-tete qui est inscrite dans Chanson
			cout << "No. " << Chanson.identificateur << endl << "Titre: " << Chanson.titre << endl << "Artiste:  " << Chanson.artiste << endl << "Album: " << Chanson.album << endl << "Annee: " << Chanson.annee << endl << "Commentaires: " << Chanson.commentaires << endl << "Genre: " << leGenre[Chanson.genre] << endl << endl;		//Affichage de l'en-tete
		}
		F_entree.close();		//Fermeture du fichier
	}
}

void Verification(int choix)		//Fonction qui verifie le choix de l'utilisateur
{
	if (choix != 1 && choix != 2 && choix != 3 && choix != 4 && choix != 5) {		//Si le choix n'est pas valide
		cout << "Votre choix doit absolument etre un chiffre compris entre 0 et 5" << endl;		//Demande a l'utilisateur d'entrer un choix valide
		cin >> choix;		//Inscris le choix de l'utilisateur dans une variable
		cout << endl;
		Verification(choix);		//Verifie si le choix de l'utilisateur est valide
	}
}

void main(void)
{	
	int choix = 0;		//Declaration de la variable qui contiendra le choix de l'usager

	do
	{
		cout << "Quelle operation desirez-vous effectuer? " << endl;		//Affichage des choix disponibles a l'utilisateur
		cout << " 1. Entrer l'en-tete d'un fichier audio " << endl;
		cout << " 2. Afficher toutes les en-tetes que contient la base de donnee " << endl;
		cout << " 3. Afficher le nombre de fichiers audio d'un genre donne " << endl;
		cout << " 4. Afficher l'en-tete d'un fichier audio a partir de son no. d'identification " << endl;
		cout << " 5. Quitter " << endl;
		cout << "Selection : ";
		cin >> choix;		//Inscris le choix de l'utilisateur dans une variable
		cout << endl;
		Verification(choix);		//Verifie si le choix de l'utilisateur est valide

		switch(choix)		//Execute la fonction qui correspond au choix de l'utilisateur
		{
		case 1 : 
			EntrerEnTete();
			break;
		case 2 : 
			AfficheEnTete();
			break;
		case 3 : 
			break;
		case 4 : 
			break;
		default:
			break;
		}
	}
	while(5 != choix);
}
 
Est-ce que le prof a demandé de commenter chaque ligne? Ca me rappelle mes début... crissement inutile haha!
 
Status
Not open for further replies.
Back
Top