Salve, lavorando ad un programma ottengo diversi errori durante la fase di compilazione per quanto riguarda il passagnio di due struct usando due puntatori.
I commenti e i nomi delle variabili, delle funzioni e delle struct sono in inglese perchè il codice è anche disponibile su GitHub
I file sorgenti sono i seguenti:
main.cpp
/* YGO's guidelines (these are more tips and not rule, so if you don't care it's fine)
Naming:
*C++ ISO standard but with upper case for your own types, variable, functions and classes
*use only letter and avoid to indicate the type of the variable in her own name.
*For more information on the C++ISO standard refer to the C++ Core Guideline in the NL section
Line lenght:
*If possible no more than 100 characters
*Avoid the use of long one line std::cout
Library:
*Use only STL library, refer to the C++17 standard
*include all the library you need in the Function.hh
* */
#include "Function.hh"
int main(){
//defining variable, pointer, struct and object
// variable
std::string Usr_Input;
char Chosen_Menu_Voice;
// Struct
struct Card_Data{
std::vector <std::string> Card_Id; // Vector for the card's id
std::vector <std::string> Card_Names; // Vector to store the names of the cards
std::vector <std::string> Card_Quantity; // Vector to store the quantity of the cards
};
struct Dir_Data{
std::vector <std::string> Dir_Names; // Vector with the name of the dirs (database)
std::string Chosen_Dir; // The dir choosen by the user
};
// Defining object
Card_Data c; // need a better name
Dir_Data d; //need a better name
// Defining pointers for passing by reference for functions
Card_Data* Card = &c;
Dir_Data* Dir = &d;
// finish defining variable
// Cute prompt, it's printend only 1 time
std::cout <<"__ ______ ___" << std::endl;
std::cout <<"\\ \\ / / ___|/ _ \\ " << std::endl;
std::cout <<" \\ V / | _| | | |"<<std::endl;
std::cout <<" | || |_| | |_| |"<<std::endl;
std::cout <<" |_| \\____|\\___/ "<<std::endl;
// Print and use of the menu
while (true)
{
std::cout <<"-------------------------------------\n";
std::cout <<"1: Choose archive\n"; // Chose the archive and take data from it
std::cout <<"2: List databases\n";
std::cout <<"3: Create a new database\n";
std::cout <<"4: Inserting a card in the database\n";
std::cout <<"5: Print all the database\n";
std::cout <<"6: Search by ID in the database\n";
std::cout <<"7: Cancel a card from the database\n";
std::cout <<"8: Close the program\n";
std::cout <<"-------------------------------------\n";
std::cin >> Chosen_Menu_Voice;
// Clearing the terminal
std::cout << "\033[2J\033[1;1H";
// Real engine of the program
switch (Chosen_Menu_Voice)
{
case '1':
chose_Dir(Dir);
take_Data_Single(Card, Dir);
break;
case '2':
search_Dirs(Dir);
break;
case '3':
create_Dir();
break;
case '4':
inserting(Card);
save_Data(Card, Dir);
break;
case '5':
print(Card);
std::cout << "Press a key to return to the menu ";
std::getchar();
break;
case '6':
research(Card);
break;
case '7':
cancel_Card(Card);
save_Data(Card, Dir);
break;
case '8':
return 0;
default:
std::cout << "If when entering a valid parameter there was an error\n";
std::cout << "report to https://github.com/Air4x/YGO-Local-Database-Manager\n";
break;
}
}
return 0;
}
Function.hh
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <filesystem>
namespace fs = std::filesystem;
// Function to take input from the user
// For input tha require the use of a string
std::string string_Input();
// For input that require the use of a int variable
int int_Input();
void create_Dir();
void search_Dirs(struct Dir_Data* Dir);
void chose_Dir(struct Dir_Data* Dir);
void take_Data_Single(struct Card_Data* Card, struct Dir_Data* Dir);
// Take the data from the 2 file and insert it in the 2 vector passed by reference
void inserting(struct Card_Data* Card);
// Insert the card name and the card id in the vector passed by reference
void print(struct Card_Data* Card);
// print on screen the data from the 2 vector passed by reference
void cancel_Card(struct Card_Data* Card);
// Cancel an ID and his correspondig name from the 2 vector
void save_Data(struct Card_Data* Card, struct Dir_Data* Dir);
// Save the data and the modifications from the 2 vector passed by reference in the 2 file
// used after the utilization of CancelCard() and Inserting()
int is_There(struct Card_Data* Card, std::string To_Find);
//controll if the value of To_Find is present in the vector and return the index of the element if present
void research(struct Card_Data* Card);
// Use the value retruned by IsThere() to create the corresponding output
Function.cpp
#include "Function.hh"
// Function to take input from the user and converting if needed
// Take an Input as a std::string and return it
std::string string_Input(){
std::string Input;
std::getline(std::cin, Input);
return Input;
}
// Take an input as a std::string convert it to int and return it
int int_Input(){
int Input;
std::string S_Input = String_Input();
Input = std::stoi(S_Input);
return Input;
}
// Function to manage dirs, like making, serching and chosing from what dir take all the data
// Create a directory using the std::string returned by string_Input(), and if .YGO/ dir doesn't exist, create it
void create_Dir(){
std::cout << "Insert the archive's name: ";
std::string Dir_Name = String_Input();
std::string Home_Dir = std::getenv("HOME");
std::string YGO_Dir = Home_Dir + "/.YGO/";
std::string Data_Dir = YGO_Dir + Dir_Name;
if(fs::exists(YGO_Dir)){
fs::create_directory(Data_Dir);
}
else{
fs::create_directory(YGO_Dir);
fs::create_directory(Data_Dir);
}
}
// the following 2 functions are used together
// Search any directory in the ~/.YGO/ dir and print it
void search_Dirs(struct ir_Data* Dir){
int c = 1; // used to count the directories
std::string SearchingDir = std::getenv("HOME");
SearchingDir /= ".YGO";
fs::path DataDir(SearchingDir);
for(auto &p : fs::directory_iterator(DataDir){
std::cout << c << ": " << p.filename() << std::endl;
DirName->push_back();
++c;
}
}
// Call search_Dirs() and ask to the user whinc dir to use
void chose_Dir(struct Dir_Data* Dir){
int Index = 0;
search_Dirs(Dir_Data* Dir);
std::cin.ignore();
std::cout << "Whinc archive you want to use? ";
std::cin >> Index;
std::cout << "\033[2J\033[1;1H";//equivalent to std::system("clear")
ChosenDir = DirName->at(Index);
}
// Function to manage the stream of data from/to the txt file where it is stored
// Take data from the files in the Dir->Chosen_Dir variable
void take_Data_Single(struct Card_Data *Card, struct Dir_Data *Dir){
std::string Dummy_Input;
std::ifstream CardNames(Dir->ChosenDir /= "CardNames.txt");
std::ifstream CardID(Dir->ChosenDir /= "CardID.txt");
std::ifstream CardQuantity(Dir->ChosenDir /= "CardQuantity.txt");
if (CardNames.is_open() && CardID.is_open() && CardQuantity.is_open())
{
while(!CardNames.eof())
{
std::getline(CardNames, Dummy_Input); // Take one line from CardNames.txt
Card->Card_Names.push_back(Dummy_Input); // Put the value of Dummy_Input
}
while (!CardID.eof())
{
std::getline(CardID, Dummy_Input);
Card->Card_Id.push_back(Dummy_Input);
}
while (!CardQuantity.eof());
{
std::getline(CardQuantity, Dummy_Input);
Card->Card_Quantity.push_back(Dummy_Input);
}
}
else
{
std::cout << "Cannot open the archive";
}
CardNames.close();
CardID.close();
CardQuantity.close();
Card->Card_Names.pop_back();
Card->Card_ID.pop_back();
Card->Card_Quantity.pop_back();
}
// Save changes made to vectors applying them to files
void save_Data(struct Card_Data* Card, struct Dir_Data* Dir){
std::ofstream CardNames(Dir->Chosen_Dir /= "CardNames.txt");
std::ofstream CardID(Dir->ChosenDir /= "CardID.txt");
std::ofstream CardQuantity(Dir->ChosenDir /= "CardQuantity.txt");
for (std::string i : Card->Card_Names)
{
CardNames << i << std::endl;
}
for (std::string i : Card->Card_ID)
{
CardID << i << std::endl;
}
for(std::string i : Card->Card-Quantity){
CardQuantity << i << std::endl;
}
CardNames.close();
CardID.close();
CardQuantity.close();
}
// The following the functions are used to modify the vectors themselves
// Adds the name, id and quantity of a card to the end of the corresponding std::vector
void inserting(struct Card_Data *Card){
std::cin.ignore();
// Declaring Dummy varables for the user's input
std::string Input_Name;
std::string Input_Id;
std::string Input_Quantity;
// Taking data from the user
std::cout << "Insert card's name: ";
std::getline(std::cin, Input_Name);
std::cout << "Insert card'id: ";
std::getline(std::cin, Input_Id);
// Inserting the data from the user's input in the two vector
Card->Card_Names.push_back(Input_Name);
Card->Card_Id.push_back(Input_Id);
Card->Card_Quantity.push_back(Input_Quantity);
}
//Delete a card from the archive by removing name, id and quantity from the corresponding vectors
void cancel_Card(struct Card_Data* Card){
int i;
std::cout << "Insert the number of the card to be canceled\n";
std::cout << "(if in doubt, use the second item of the main menu)\n";
std::cout << "Number of the card: ";
std::cin >> i;
if (i == 1){
Card->Card_Names.erase(Name->begin());
Card->Card_Id.erase(ID->begin());
Card->Card_Quantity.erase(Quantity->begin());
}
else{
Card->Card_Names.erase(Card->Card_Names.begin() + i);
Card->Card_Id.erase(Card->Card_Id.begin() + i);
Card->Card_Quantity.erase(Card->Card_Quantity.begin() + i);
}
}
// Print to screen neme, id and quantity of every card taking the data from the vectors using the same index for every card
void print(struct Card_Data* Card){
std::cin.ignore();
int Index = 0;
int Size_Name;
int Size_ID;
int Size_Quantity;
Size_Name = Card->Card_Names.size();
Size_ID = Card->Card_Id.size();
Size_Quantity = Card->Card_Quantity.size();
if(Size_Name == Size_ID && Size_ID == Size_Quantity){
while(Index < Size_Name){
std::cout << Index + 1;
std::cout << " Name: " << Card->Card_Names.at(Index);
std::cout << " Id: " << Card->Card_Id.at(Index);
std::cout << " Amount: " << Card->Card_Quantity.at(Index) << std::endl;
++Index;
}
}
}
// The 2 folling function are used together to serch a specific ID in the archive
// Verify if the submitted ID is present in the archive and return is index, if not return a -1 code error
int is_There(struct Card_Data* Card, std::string To_Find){
for(int i = 0; i < Card->Card_Id.size(); ++i){
if(Card->Card_Id.at(i) == To_Find){
return i;
}
}
return -1;
}
// Call is_There() and use the return value to make an opportune outuput
void research(struct Card_Data* Card){
std::cin.ignore();
std::cout << "Card's ID: ";
std::string To_Find = string_Input();
int Output_Flag = IsThere(ID, To_Find);
if(Output_Flag < 0){
std::cout << "The card is not present in the database\n";
}
else{
std::cout << "The card was found!\n";
std::cout << "Name: " << Card->Card_Names.at(Output_Flag);
std::cout << " ID: " << Card->Card_Id.at(Output_Flag);
std::cout << " Amount: " << Card->Card_Quantity.at(Output_Flag)<< std::endl;
}
}
Il programma ha come scopo quello di gestire degli "archivi" (tre file di testo semplice all'interno di particolari cartelle) per poter gestire carte di Yu-Gi-Oh, questo lo fa copiando il contenuto dei file in tre std::vector che sono raggruppati all'interno di una struct di nome Card_Data, usa un approcio simile per gestire le cartelle.
Il sistema operativo su cui compilo il programma è EndevourOS, distro linux basata su Arch.
Come compilatore utilizzo il gcc 10.2.0
Come parametro particolare per la compilazione uso soltanto -std=C++17 per abilitare il supporto all'omonimo standard.
L'output del compilatore può essere trovato a questo link:
https://pastebin.com/wprNnup
Vi avverto che sono 8 pagine di errori, io non sono riuscito a leggerli tutti senza avere mal di testa, forse Voi riuscite a capirne qualcosa di più.