Risolto Ho degli errori (risolto)

Super Pesce

Utente Iron
23 Dicembre 2021
11
1
0
6
Ultima modifica:
C++:
#include <iostream>
#include <string>
using namespace std;

struct libro {
    string nome;
    int anno;
    bool operator==(const libro&) const = default;
    bool operator==(int i) { return anno == i; }
    bool operator<(int i) { return anno < i; }
};

struct libreria {
    libro L[100];
    int n;
};

void Carica(libreria& o) {
    for (int i = 0; i < o.n; i++) {
        cout << "Inserisci nome libro: ";
        cin >> o.L[i].nome;
        cout << "Inserisci anno libro: ";
        cin >> o.L[i].anno;
    }
}

void Mostra(libreria& o) {
    for (int i = 0; i < o.n; i++) {
        cout << "Nome del libro: " << o.L[i].nome << " (" << o.L[i].anno << ")" << endl;
    }
}

void Elimina(libreria& o, int x) {
    for (int i = 0; i < o.n; i++) {
        if (o.L[i] == x) {
            for (int j = i; j < o.n; j++) {
                libro b = o.L[j];
                o.L[j] = o.L[j + 1];
                o.L[j + 1] = b;
            }
            i--;
            o.n--;
        }
    }

}

void Ordinamento(libreria& o) {
    bool scambio = true;
    while ((o.n > 1) and (scambio == true)) {
        scambio = false;
        int i = 0;
        while (i < o.n - 1) {
            if (o.L[i].anno > o.L[i + 1].anno) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            } else if ((o.L[i].anno == o.L[i + 1].anno) and (o.L[i].nome > o.L[i + 1].nome)) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            }
            i--;
        }
        o.n--;
    }
}

int Ricerca(libreria& o, int s, int d, int y) {
    if (s < d) {
        int m = (s + d) / 2;
        if (o.L[m] == y) {
            return m;
        } else if (o.L[m] < y) {
            return Ricerca(o, m + 1, d, y);
        } else {
            return Ricerca(o, s, m - 1, y);
        }
    } else {
        return -1;
    }
}

int main() {

    libreria b;
    cout << "Numero di libri da inserire: ";
    cin >> b.n;

    Carica(b);

    Ordinamento(b);

    int x;
    cout << "Elemento da eliminare: ";
    cin >> x;

    Elimina(b, x);

    int y;
    cout << "Elemento da ricercare: ";
    cin >> y;

    int n;
    Ricerca(b, 0, n, y);

    Mostra(b);

    return 0;
}
 
Ciao!
Consiglio per ottenere risposte piu' facilmente: inserisci il codice nel tag [ CODE] (trovi il simbolo ' </> ' quando scrivi la discussione! Cosi' il codice sara' ben formattato e leggibile!

Inoltre non hai riportato alcun errore
Ed il titolo della discussione quindi non aiuta a capire quale sia il tuo problema
(Perche' il titolo in inglese se poi e' tutto in italiano?)
 
Ciao!
Consiglio per ottenere risposte piu' facilmente: inserisci il codice nel tag [ CODE] (trovi il simbolo ' </> ' quando scrivi la discussione! Cosi' il codice sara' ben formattato e leggibile!

Inoltre non hai riportato alcun errore
Ed il titolo della discussione quindi non aiuta a capire quale sia il tuo problema
(Perche' il titolo in inglese se poi e' tutto in italiano?)
Ciao, pensavo fosse un forum in inglese perciò, comunque come errori mi da questi:
Codice:
8    [Error] 'bool libro::operator==(const libro&) const' cannot be defaulted
34    [Error] no match for 'operator==' (operand types are 'libro' and 'int')
74    [Error] no match for 'operator==' (operand types are 'libro' and 'int')
77    [Error] no match for 'operator<' (operand types are 'libro' and 'int')
Sto utilizzando come programma Dev-C++ 5.11
 
Ciao, pensavo fosse un forum in inglese perciò, comunque come errori mi da questi:
Codice:
8    [Error] 'bool libro::operator==(const libro&) const' cannot be defaulted
34    [Error] no match for 'operator==' (operand types are 'libro' and 'int')
74    [Error] no match for 'operator==' (operand types are 'libro' and 'int')
77    [Error] no match for 'operator<' (operand types are 'libro' and 'int')
Sto utilizzando come programma Dev-C++ 5.11
Il problema e' che, a quanto pare, stai cercando di comparare un oggetto libro con un intero.
Formatta il codice come ti ho consigliato prima (nel tag che ti ho spiegato, basta modificare la discussione), cosi' il codice sara' piu' comprensibile potremo aiutarti piu' facilmente!
 
Ordinamento cosa deve fare? Ordinare i libri in base al nome o in base all'anno?

Elimina cosa deve fare? Eliminare l'i-esimo elemento dalla lista, eliminare i libri (il primo o tutti?) che hanno un certo anno oppure prendere nome e anno in input ed eliminare il libro (il primo o tutti?) con quel nome e quell'anno?

Ricerca cosa deve fare? Trovare il (il primo o tutti?) libro con un certo anno oppure prendere nome e anno in input ed trovare il libro (il primo o tutti?) con quel nome e quell'anno?
 
Dovresti ridefinire l'operatore == (spiegando quindi cosa deve confrontare per considera due libri uguali)

In seguito, nella funzione "elimina":

Codice:
if (o.L[i] == x)
indica che tu vuoi accedere al libro nella posizione i della lista L dell'oggetto libreria o

Questo oggetto e' un libro, ma tu lo stai comparando ad un libro, quindi ti da' errore.

Cosa vuoi indicare con quel numero? Il codice identificativo del libro? In tal caso dovresti inserire anche una variabile (ID per esempio) per ogni libro, in modo da identificarlo univocamente. Inoltre ti consiglio di usare le funzioni set e get per accedere agli oggetti, cosi' (qualora la tua intenzione sia questa) potrai confrontare l'ID del libro con la 'x' ricevuta in input (che suppongo appunto sia l'ID del libro stesso)
 
Ultima modifica:
Ordinamento cosa deve fare? Ordinare i libri in base al nome o in base all'anno?

Elimina cosa deve fare? Eliminare l'i-esimo elemento dalla lista, eliminare i libri (il primo o tutti?) che hanno un certo anno oppure prendere nome e anno in input ed eliminare il libro (il primo o tutti?) con quel nome e quell'anno?

Ricerca cosa deve fare? Trovare il (il primo o tutti?) libro con un certo anno oppure prendere nome e anno in input ed trovare il libro (il primo o tutti?) con quel nome e quell'anno?
Prima in base al nome poi anno, elimina un certo anno e ricerca l'anno
Messaggio unito automaticamente:

Dovresti ridefinire l'operatore == (spiegando quindi cosa deve confrontare per considera due libri uguali)

In seguito, nella funzione "elimina":

Codice:
if (o.L[i] == x)
indica che tu vuoi accedere al libro nella posizione i della lista L dell'oggetto libreria o

Questo oggetto e' un libro, ma tu lo stai comparando ad un libro, quindi ti da' errore.

Cosa vuoi indicare con quel numero? Il codice identificativo del libro? In tal caso dovresti inserire anche una variabile (ID per esempio) per ogni libro, in modo da identificarlo univocamente. Inoltre ti consiglio di usare le funzioni set e get per accedere agli oggetti, cosi' (qualora la tua intenzione sia questa) potrai confrontare l'ID del libro con la 'x' ricevuta in input (che suppongo appunto sia l'ID del libro stesso)
con x indico l'anno del libro che voglio eliminare
Messaggio unito automaticamente:

Ho risolto la maggior parte dei problemi ma mi rimane un avviso: Dati non validi: nell'accesso a 'o.L', la dimensione leggibile è '4800' byte, ma è possibile leggere '-48' byte.

Se volete vi posso anche mettere il codice completo oltre a questo ordinamento

C++:
void Ordinamento(libreria& o) {
    bool scambio = true;
    while ((o.n > 1) and (scambio = true)) {
        scambio = false;
        int i = 0;
        while (i < o.n - 1) {
            if (o.L[i].anno > o.L[i + 1].anno) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            }
            else if ((o.L[i].anno == o.L[i + 1].anno) and (o.L[i].nome > o.L[i + 1].nome)) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            }
            i--;
        }
        o.n--;
    }
}
 
Prima in base al nome poi anno, elimina un certo anno e ricerca l'anno
Se l'ordinamento è prima in base al nome e poi (se hanno lo stesso nome) in base all'anno, allora non puoi fare la ricerca dicotomica (che stai usando ora) per la ricerca. Probabilmente vuoi fare il contrario... che è quello che stai effettivamente tentando di fare nel codice.

Togli l'operator overloading su libro. Vedo che non lo stai usando in Ordinamento e dato l'esercizio immagino che tu non li abbia ancora studiati.
C++:
struct libro {
    string nome;
    int anno;
};

La funzione elimina la puoi correggere in questo modo:
C++:
void Elimina(libreria& o, int x) {
    for (int i = 0; i < o.n; i++) {
        if (o.L[i].anno == x) {
            libro b = o.L[i]; // non serve, ma vabbé...
            for (int j = i; j < o.n - 1; j++) {
                o.L[j] = o.L[j + 1];
            }
            i--;
            o.n--;
            o.L[o.n] = b; // non serve, ma vabbé...
        }
    }
}

La funzione Ordinamento la puoi correggere in questo modo:
C++:
void Ordinamento(libreria& o) {
    int n = o.n; // non vuoi che l'ordinamento decrementi veramente o.n
    bool scambio = true;
    while ((n > 1) and (scambio == true)) {
        scambio = false;
        int i = 0;
        while (i < n - 1) {
            if (o.L[i].anno > o.L[i + 1].anno) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            } else if ((o.L[i].anno == o.L[i + 1].anno) and (o.L[i].nome > o.L[i + 1].nome)) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            }
            i++; // ++ non --
        }
        n--;
    }
}

Senza operator overloading, la funzione Ricerca la puoi correggere in questo modo:
C++:
int Ricerca(libreria& o, int s, int d, int y) {
    if (s < d) {
        int m = (s + d) / 2;
        if (o.L[m].anno == y) { // aggiunto .anno
            return m;
        } else if (o.L[m].anno < y) { // aggiunto .anno
            return Ricerca(o, m + 1, d, y);
        } else {
            return Ricerca(o, s, m - 1, y);
        }
    } else {
        return -1;
    }
}

E nel main realisticamente vuoi una cosa di questo tipo:
C++:
int t = Ricerca(b, 0, b.n, y); // b.n non n
cout << "Posizione: " << t << "\n";

Nota che certe cose si possono fare in modo più pulito. In Ordinamento, ad esempio, avresti potuto usare || invece di fare un else if identico. Ho preferito modificare il meno possibile il tuo codice, almeno capisci meglio dove stavano gli errori.
 
Se l'ordinamento è prima in base al nome e poi (se hanno lo stesso nome) in base all'anno, allora non puoi fare la ricerca dicotomica (che stai usando ora) per la ricerca. Probabilmente vuoi fare il contrario... che è quello che stai effettivamente tentando di fare nel codice.

Togli l'operator overloading su libro. Vedo che non lo stai usando in Ordinamento e dato l'esercizio immagino che tu non li abbia ancora studiati.
C++:
struct libro {
    string nome;
    int anno;
};

La funzione elimina la puoi correggere in questo modo:
C++:
void Elimina(libreria& o, int x) {
    for (int i = 0; i < o.n; i++) {
        if (o.L[i].anno == x) {
            libro b = o.L[i]; // non serve, ma vabbé...
            for (int j = i; j < o.n - 1; j++) {
                o.L[j] = o.L[j + 1];
            }
            i--;
            o.n--;
            o.L[o.n] = b; // non serve, ma vabbé...
        }
    }
}

La funzione Ordinamento la puoi correggere in questo modo:
C++:
void Ordinamento(libreria& o) {
    int n = o.n; // non vuoi che l'ordinamento decrementi veramente o.n
    bool scambio = true;
    while ((n > 1) and (scambio == true)) {
        scambio = false;
        int i = 0;
        while (i < n - 1) {
            if (o.L[i].anno > o.L[i + 1].anno) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            } else if ((o.L[i].anno == o.L[i + 1].anno) and (o.L[i].nome > o.L[i + 1].nome)) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            }
            i++; // ++ non --
        }
        n--;
    }
}

Senza operator overloading, la funzione Ricerca la puoi correggere in questo modo:
C++:
int Ricerca(libreria& o, int s, int d, int y) {
    if (s < d) {
        int m = (s + d) / 2;
        if (o.L[m].anno == y) { // aggiunto .anno
            return m;
        } else if (o.L[m].anno < y) { // aggiunto .anno
            return Ricerca(o, m + 1, d, y);
        } else {
            return Ricerca(o, s, m - 1, y);
        }
    } else {
        return -1;
    }
}

E nel main realisticamente vuoi una cosa di questo tipo:
C++:
int t = Ricerca(b, 0, b.n, y); // b.n non n
cout << "Posizione: " << t << "\n";

Nota che certe cose si possono fare in modo più pulito. In Ordinamento, ad esempio, avresti potuto usare || invece di fare un else if identico. Ho preferito modificare il meno possibile il tuo codice, almeno capisci meglio dove stavano gli errori.
Grazie mille
Messaggio unito automaticamente:

Se l'ordinamento è prima in base al nome e poi (se hanno lo stesso nome) in base all'anno, allora non puoi fare la ricerca dicotomica (che stai usando ora) per la ricerca. Probabilmente vuoi fare il contrario... che è quello che stai effettivamente tentando di fare nel codice.

Togli l'operator overloading su libro. Vedo che non lo stai usando in Ordinamento e dato l'esercizio immagino che tu non li abbia ancora studiati.
C++:
struct libro {
    string nome;
    int anno;
};

La funzione elimina la puoi correggere in questo modo:
C++:
void Elimina(libreria& o, int x) {
    for (int i = 0; i < o.n; i++) {
        if (o.L[i].anno == x) {
            libro b = o.L[i]; // non serve, ma vabbé...
            for (int j = i; j < o.n - 1; j++) {
                o.L[j] = o.L[j + 1];
            }
            i--;
            o.n--;
            o.L[o.n] = b; // non serve, ma vabbé...
        }
    }
}

La funzione Ordinamento la puoi correggere in questo modo:
C++:
void Ordinamento(libreria& o) {
    int n = o.n; // non vuoi che l'ordinamento decrementi veramente o.n
    bool scambio = true;
    while ((n > 1) and (scambio == true)) {
        scambio = false;
        int i = 0;
        while (i < n - 1) {
            if (o.L[i].anno > o.L[i + 1].anno) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            } else if ((o.L[i].anno == o.L[i + 1].anno) and (o.L[i].nome > o.L[i + 1].nome)) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            }
            i++; // ++ non --
        }
        n--;
    }
}

Senza operator overloading, la funzione Ricerca la puoi correggere in questo modo:
C++:
int Ricerca(libreria& o, int s, int d, int y) {
    if (s < d) {
        int m = (s + d) / 2;
        if (o.L[m].anno == y) { // aggiunto .anno
            return m;
        } else if (o.L[m].anno < y) { // aggiunto .anno
            return Ricerca(o, m + 1, d, y);
        } else {
            return Ricerca(o, s, m - 1, y);
        }
    } else {
        return -1;
    }
}

E nel main realisticamente vuoi una cosa di questo tipo:
C++:
int t = Ricerca(b, 0, b.n, y); // b.n non n
cout << "Posizione: " << t << "\n";

Nota che certe cose si possono fare in modo più pulito. In Ordinamento, ad esempio, avresti potuto usare || invece di fare un else if identico. Ho preferito modificare il meno possibile il tuo codice, almeno capisci meglio dove stavano gli errori.
Tipo così?
C++:
void Ordinamento(libreria& o) {
    int n = o.n;
    bool scambio = true;
    while ((n > 1) and (scambio == true)) {
        scambio = false;
        int i = 0;
        while (i < n - 1) {
            if ((o.L[i].anno > o.L[i + 1].anno)or((o.L[i].anno == o.L[i + 1].anno) and (o.L[i].nome > o.L[i + 1].nome))) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            }
            i++;
        }
        n--;
    }
}
 
Più o meno, ma ricordati che and e or in C++ si fanno rispettivamente con && e ||, la sintassi che hai usato tu esiste ma non la usa nessuno. È stata introdotta perché alcune tastiere non hanno quei simboli e quelli di C++ volevano aderire a uno standard più generale, ma please no... usa la sintassi normale.

Poi volevo chiederti come fare quando voglio inserire invece di un solo nome anche più parole con spazi, mi sembra tipo getline ma non so
Esatto, al posto di scrivere cin >> pippo; devi scrivere getline(cin, pippo);
 
Ultima modifica:
Più o meno, ma ricordati che and e or in C++ si fanno rispettivamente con && e ||, la sintassi che hai usato tu esiste ma non la usa nessuno. È stata introdotta perché alcune tastiere non hanno quei simboli e quelli di C++ volevano aderire a uno standard più generale, ma please no... usa la sintassi normale.


Esatto, al posto di scrivere cin >> pippo; devi scrivere getline(cin, pippo);
Tipo così?
C++:
void Carica(libreria& o) {
    for (int i = 0; i < o.n; i++) {
        cout << "Inserisci nome libro: ";
        getline(cin, o.L[i].nome);
        cout << "Inserisci anno libro: ";
        cin >> o.L[i].anno;
    }
}

Però sul cmd esce questo
C++:
Numero di libri da inserire: 4
Inserisci nome libro: Inserisci anno libro: marco
Inserisci nome libro: Inserisci anno libro: Inserisci nome libro: Inserisci anno libro: Inserisci nome libro: Inserisci anno libro: Nome da eliminare: Nome da ricercare: Posizione: -1
Libreria ordinata per nome:
e poi il programma termina
 
Tipo così?
C++:
void Carica(libreria& o) {
    for (int i = 0; i < o.n; i++) {
        cout << "Inserisci nome libro: ";
        getline(cin, o.L[i].nome);
        cout << "Inserisci anno libro: ";
        cin >> o.L[i].anno;
    }
}

Però sul cmd esce questo
C++:
Numero di libri da inserire: 4
Inserisci nome libro: Inserisci anno libro: marco
Inserisci nome libro: Inserisci anno libro: Inserisci nome libro: Inserisci anno libro: Inserisci nome libro: Inserisci anno libro: Nome da eliminare: Nome da ricercare: Posizione: -1
Libreria ordinata per nome:
e poi il programma termina
L'input non funziona correttamente, l'utente non ha la possibilità di inserirlo. C'è della sporcizia nel buffer stdin.

La soluzione che discuto nelle FAQ è da inserire appena prima del getline. Potrebbe interessarti anche tutto il resto del thread oltre che al primo messaggio.
 
L'input non funziona correttamente, l'utente non ha la possibilità di inserirlo. C'è della sporcizia nel buffer stdin.

La soluzione che discuto nelle FAQ è da inserire appena prima del getline. Potrebbe interessarti anche tutto il resto del thread oltre che al primo messaggio.
Ciao scusa se ti ho fatto aspettare, mettendo questo codice mi prende tutta la riga ma le altre funzioni come l'eliminazione non vanno.
C++:
void Carica(libreria& o) {
    for (int i = 0; i < o.n; i++) {
        cout << "Inserisci nome libro: ";
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        cin.clear();
        getline(cin, o.L[i].nome);
        cout << "Inserisci anno libro: ";
        cin >> o.L[i].anno;
    }
}
 
Questo è l'imput.
C++:
#include <iostream>
#include <string>
using namespace std;

struct libro {
    string nome{};
    int anno{};
};

struct libreria {
    libro L[100]{};
    int n{};
};

void Carica(libreria& o) {
    for (int i = 0; i < o.n; i++) {
        cout << "Inserisci nome libro: ";
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        cin.clear();
        getline(cin, o.L[i].nome);
        cout << "Inserisci anno libro: ";
        cin >> o.L[i].anno;
    }
}

void Mostra(libreria& o) {
    cout << "Libreria ordinata per nome: "<<endl;
    for (int i = 0; i < o.n; i++) {
        cout << "Nome del libro: " << o.L[i].nome << " (" << o.L[i].anno << ")" << endl;

    }
}

void Elimina(libreria& o, string x) {
    for (int i = 0; i < o.n; i++) {
        if (o.L[i].nome == x) {
            for (int j = i; j < o.n - 1; j++) {
                o.L[j] = o.L[j + 1];
            }
            i--;
            o.n--;
        }
    }
}

void Ordinamento(libreria& o) {
    int n = o.n;
    bool scambio = true;
    while ((n > 1) && (scambio == true)) {
        scambio = false;
        int i = 0;
        while (i < n - 1) {
            if ((o.L[i].nome > o.L[i + 1].nome)||((o.L[i].nome == o.L[i + 1].nome) && (o.L[i].anno > o.L[i + 1].anno))) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            }
            i++;
        }
        n--;
    }
}

int Ricerca(libreria& o, int s, int d, string y) {
    if (s < d) {
        int m = (s + d) / 2;
        if (o.L[m].nome == y) {
            return m;
        }
        else if (o.L[m].nome < y) {
            return Ricerca(o, m + 1, d, y);
        }
        else {
            return Ricerca(o, s, m - 1, y);
        }
    }
    else {
        return -1;
    }
}

int main() {

    libreria b;
    cout << "Numero di libri da inserire: ";
    cin >> b.n;

    Carica(b);

    Ordinamento(b);

    string x;
    cout << "Nome da eliminare: ";
    cin >> x;

    Elimina(b, x);

    string y;
    cout << "Nome da ricercare: ";
    cin >> y;

    int t = Ricerca(b, 0, b.n, y);
    cout << "Posizione: " << t <<endl;

    Mostra(b);

    return 0;
}
Questo è l'output.
C++:
Numero di libri da inserire: 2
Inserisci nome libro: Harry potter
Inserisci anno libro: 1948
Inserisci nome libro: Anna belle
Inserisci anno libro: 2000
Nome da eliminare: Anna belle
Nome da ricercare: Posizione: -1
Libreria ordinata per nome:
Nome del libro: Anna belle (2000)
Nome del libro: Harry potter (1948)
 
Ah okay, non stai più facendo la ricerca e l'eliminazione in base all'anno ma in base al nome. Per leggere stringhe con gli spazi (nel main) devi usare getline e non l'operatore >> di cin. Se avrai ancora il problema di prima (ti salta qualche input o roba del genere) puoi riferirti nuovamente al link che ti ho girato prima.
 
Ultima modifica:
Ah okay, non stai più facendo la ricerca e l'eliminazione in base all'anno ma in base al nome. Per leggere stringhe con gli spazi (nel main) devi usare getline e non l'operatore >> di cin. Se avrai ancora il problema di prima (ti salta qualche input o roba del genere) puoi riferirti nuovamente al link che ti ho girato prima.
Come output ho questo
Codice:
Numero di libri da inserire: 3
Inserisci nome libro: x
Inserisci anno libro: 4545
Inserisci nome libro: d
Inserisci anno libro: 45665
Inserisci nome libro: a
Inserisci anno libro: 98522
Nome da eliminare: d
Nome da ricercare: a

Posizione: -1
Libreria ordinata per nome:
Nome del libro: a (98522)
Nome del libro: x (4545)
e se dove c'è lo spazio inserisco qualsiasi altra cosa che non sia invio non funziona
Messaggio unito automaticamente:

Come output ho questo
Codice:
Numero di libri da inserire: 3
Inserisci nome libro: x
Inserisci anno libro: 4545
Inserisci nome libro: d
Inserisci anno libro: 45665
Inserisci nome libro: a
Inserisci anno libro: 98522
Nome da eliminare: d
Nome da ricercare: a

Posizione: -1
Libreria ordinata per nome:
Nome del libro: a (98522)
Nome del libro: x (4545)
e se dove c'è lo spazio inserisco qualsiasi altra cosa che non sia invio non funziona
Questo è tutto il codice
C++:
#include <iostream>
#include <string>
using namespace std;

struct libro {
    string nome{};
    int anno{};
};

struct libreria {
    libro L[100]{};
    int n{};
};

void Carica(libreria& o) {
    for (int i = 0; i < o.n; i++) {
        cout << "Inserisci nome libro: ";
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        cin.clear();
        getline(cin, o.L[i].nome);
        cout << "Inserisci anno libro: ";
        cin >> o.L[i].anno;
    }
}

void Mostra(libreria& o) {
    cout << "Libreria ordinata per nome: "<<endl;
    for (int i = 0; i < o.n; i++) {
        cout << "Nome del libro: " << o.L[i].nome << " (" << o.L[i].anno << ")" << endl;

    }
}

void Elimina(libreria& o, string x) {
    for (int i = 0; i < o.n; i++) {
        if (o.L[i].nome == x) {
            for (int j = i; j < o.n - 1; j++) {
                o.L[j] = o.L[j + 1];
            }
            i--;
            o.n--;
        }
    }
}

void Ordinamento(libreria& o) {
    int n = o.n;
    bool scambio = true;
    while ((n > 1) && (scambio == true)) {
        scambio = false;
        int i = 0;
        while (i < n - 1) {
            if ((o.L[i].nome > o.L[i + 1].nome)||((o.L[i].nome == o.L[i + 1].nome) && (o.L[i].anno > o.L[i + 1].anno))) {
                libro y = o.L[i];
                o.L[i] = o.L[i + 1];
                o.L[i + 1] = y;
                scambio = true;
            }
            i++;
        }
        n--;
    }
}

int Ricerca(libreria& o, int s, int d, string y) {
    if (s < d) {
        int m = (s + d) / 2;
        if (o.L[m].nome == y) {
            return m;
        }
        else if (o.L[m].nome < y) {
            return Ricerca(o, m + 1, d, y);
        }
        else {
            return Ricerca(o, s, m - 1, y);
        }
    }
    else {
        return -1;
    }
}

int main() {

    libreria b;
    cout << "Numero di libri da inserire: ";
    cin >> b.n;

    Carica(b);

    Ordinamento(b);

    string x;
    cout << "Nome da eliminare: ";
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    cin.clear();
    getline(cin, x);

    Elimina(b, x);

    string y;
    cout << "Nome da ricercare: ";
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    cin.clear();
    getline(cin, y);

    int t = Ricerca(b, 0, b.n, y);
    cout << "Posizione: " << t <<endl;

    Mostra(b);

    return 0;
}
 
Ultima modifica:
Il -1 ce l'hai perché la ricerca è buggata. Dipende da come scegli di implementarla ai bordi (range inclusi o esclusi), ma il modo più semplice per sistemarla è togliendo il -1 e lasciando il range [chiuso .. aperto), in questo modo:
C++:
int Ricerca(libreria& o, int s, int d, string y) {
    if (s < d) {
        int m = (s + d) / 2;
        if (o.L[m].nome == y) {
            return m;
        }
        else if (o.L[m].nome < y) {
            return Ricerca(o, m + 1, d, y);
        }
        else {
            return Ricerca(o, s, m, y); // nota: ho tolto -1 perché m non è incluso nel range
        }
    }
    else {
        return -1;
    }
}

Sistemato questo e usando il codice che hai postato prima io riesco ad eseguire correttamente il tuo ultimo esempio. Resta da sistemare l'input con gli spazi, che si sistema introducendo le getline anche nel main. Nota bene che il flush di stdin (le due righe di codice che hai copiato dal link che ti ho fornito) è da aggiungere solo quando necessario. Nel link che ti ho girato c'è una mini sezione "Come capisco se ho questo problema?", se quel problema non occorre non devi fare il flush.

Fai un tentativo e vedi se riesci da solo. Se hai ancora problemi posta il tuo tentativo, scrivimi ancora l'input che ti sta dando problemi e te lo sistemo io.

EDIT: ho notato solo ora il messaggio unito, il problema è che hai "fixato il problema" anche dove non si presentava.
C++:
    string y;
    cout << "Nome da ricercare: ";
    // cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  ELIMINA
    // cin.clear();  ELIMINA
    getline(cin, y);
 
Il -1 ce l'hai perché la ricerca è buggata. Dipende da come scegli di implementarla ai bordi (range inclusi o esclusi), ma il modo più semplice per sistemarla è togliendo il -1 e lasciando il range [chiuso .. aperto), in questo modo:
C++:
int Ricerca(libreria& o, int s, int d, string y) {
    if (s < d) {
        int m = (s + d) / 2;
        if (o.L[m].nome == y) {
            return m;
        }
        else if (o.L[m].nome < y) {
            return Ricerca(o, m + 1, d, y);
        }
        else {
            return Ricerca(o, s, m, y); // nota: ho tolto -1 perché m non è incluso nel range
        }
    }
    else {
        return -1;
    }
}

Sistemato questo e usando il codice che hai postato prima io riesco ad eseguire correttamente il tuo ultimo esempio. Resta da sistemare l'input con gli spazi, che si sistema introducendo le getline anche nel main. Nota bene che il flush di stdin (le due righe di codice che hai copiato dal link che ti ho fornito) è da aggiungere solo quando necessario. Nel link che ti ho girato c'è una mini sezione "Come capisco se ho questo problema?", se quel problema non occorre non devi fare il flush.

Fai un tentativo e vedi se riesci da solo. Se hai ancora problemi posta il tuo tentativo, scrivimi ancora l'input che ti sta dando problemi e te lo sistemo io.

EDIT: ho notato solo ora il messaggio unito, il problema è che hai "fixato il problema" anche dove non si presentava.
C++:
    string y;
    cout << "Nome da ricercare: ";
    // cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  ELIMINA
    // cin.clear();  ELIMINA
    getline(cin, y);
Perfetto grazie, tutto risolto