Terve. Olen joskus vuosia sitten koittanut opiskella C ja C++ mutta aloitin nyt uudestaan pari päivää sitten. Teen tällaisia turhia harjoitussovelluksia vielä, mutta törmään jatkuvasti samantyyppisiin ongelmiin joihin en keksi vastausta.
Alla olevassa koodissa on ongelmana ainakin se, että päävalikon vaihtoehdon valinta toimii vain kerran. Seuraavan kerran kun tullaan valikkoon, ohjelma päättyy, painaa sitten 1,2 tai 3. Olisin kiitollinen jos joku noheva koodari kertoisi mistä tämä johtuu. Ei taida kääntyä windowsille koska on tuo system("clear"); mikä tyhjentää terminaali-ikkunan. Olen nyt jo vähän satunnaisesti ripotellut noita selection=0; ja cin.clear(); loitsuja sinne tänne, koska ensin ongelmana oli, että jos yritti cin >> int ja käyttäjä syötti merkin char niin koko paska alkoi vilistä silmissä ja kaatui segmentation faultiin.
#include <iostream> #include <string> #include <stdlib.h> #include <sstream> #include <fstream> using namespace std; unsigned int get_menu_selection(void); //näyttää valikon ja palauttaa valinnan void add_user(void); //lisää käyttäjän void save_to_file (string first, string last); //tallentaa tiedostoon void list_users(void); //ulostaa käyttäjät ruudulle int main() { int selection = 0; selection = get_menu_selection(); cout << selection; switch (selection) { case 1: add_user(); break; case 2: list_users(); break; case 3: exit(0); break; default: get_menu_selection(); break; return 0; } } unsigned int get_menu_selection(void) { int selection=0; system("clear"); cin.clear(); cout << "***********************************" << endl; cout << " MENU " << endl; cout << "************************************" << endl; cout << "1) Add new user" << endl; cout << "2) List users" << endl; cout << "3) Exit" << endl; cout << "=====================================" << endl; cout << "Your selection:"; cin >> selection; cin.ignore('\n', 10); if (cin.fail()) { cout << "Input error!" << endl; cin.clear(); cin.ignore('\n',10); get_menu_selection(); } //valinnan oltava väliltä 1-3 tai palataan takaisin while (selection > 0 & selection < 4) { return selection; } get_menu_selection(); } void add_user(void) { string firstname, lastname, yesno; system("clear"); cout << "**************************" << endl; cout << " ADD USER " << endl; cout << "**************************" << endl; cout << "Firstname: "; cin >> ws >> firstname; cout << "Lastname: "; cin >> ws >> lastname; cout << firstname << ", " << lastname << ". Is this correct?(y/n)" << endl; cin >> ws >> yesno; if (yesno == "y") save_to_file(firstname, lastname); else if (yesno == "n") add_user(); else { cout << "invalid selection! Answer y or n!"; cin.clear(); cin.ignore('\n', 10); cin.get(); add_user(); } } void save_to_file(string firstname, string lastname) { ofstream objFile ("names.txt", ios::app); if (!objFile) { cerr << "Error opening file!!"; exit (1); } objFile << firstname << "\t\t" << lastname << endl; objFile.close(); cout << "\nInformation saved!\n"; cin.ignore('\n', 10); cin.get(); get_menu_selection(); } void list_users (void) { string line; system ("clear"); cout << "**************************" << endl; cout << " AVAILABLE USERS " << endl; cout << "**************************\n" << endl; cout << "Firstname\t" << "Lastname" << endl; cout << "---------\t" << "--------" << endl; fstream readfile; readfile.open ("names.txt", ios::in); if (readfile.fail()) { cout << "OOPS! Error opening file!" << endl; cin.ignore('\n', 10); cin.get(); get_menu_selection(); } while (readfile.peek() != EOF) { getline (readfile, line); cout << line << endl; } readfile.close(); cin.ignore('\n', 10); cin.get(); get_menu_selection(); }
int main() { // Kysyy käyttäjän valinnan int selection = 0; selection = get_menu_selection(); cout << selection; // Tekee jotain valinnan perusteella switch (selection) { case 1: add_user(); break; case 2: list_users(); break; case 3: exit(0); break; default: get_menu_selection(); break; // Lopettaa ohjelman (Ei muuten kannata jättää switch:n sisälle) return 0; } }
Sinulla ei ole silmukka-rakennetta joka pitäisi ohjelman käynnissä. Esim do...while.
default: get_menu_selection(); break; // Lopettaa ohjelman (Ei muuten kannata jättää switch:n sisälle) return 0; } }
Just sen jälkeen kun olin pastennut koodin tänne, huomasin tuon saman. Nyt siis näyttää tältä:
nt main() { int selection = 0; selection = get_menu_selection(); cout << selection; switch (selection) { case 1: add_user(); break; case 2: list_users(); break; case 3: exit(0); break; default: get_menu_selection(); break; } return 0; } Eli return 0 on nyt switchin ulkopuolella, mutta ohjelma käyttäytyy täysin samalla tavalla
Lisäys:
Äh, olipas ratkaisu simppeli. Pähkäilin tämän kanssa tuntikausia ja tajusin syyn melkein heti kun sain siitä avautua muille :)
Ongelmana oli se, että ohjelma pyöritti käyttäjää takaisin get_menu_selection -aliohjelmaan kun olisi pitänyt heittää takaisin main()-funktioon.
ture kirjoitti:
Ongelmana oli se, että ohjelma pyöritti käyttäjää takaisin get_menu_selection -aliohjelmaan kun olisi pitänyt heittää takaisin main()-funktioon.
Et kai kutsu main()-funktiota? C++-standardin mukaan niin ei saa tehdä, ja silmukka on muutenkin parempi ratkaisu.
int main() { while (true) { int selection = get_menu_selection(); cout << selection; switch (selection) { case 1: add_user(); break; case 2: list_users(); break; case 3: exit(0); break; } } }
Mikähän siinä sisennyksessäkin on niin vaikeaa. Kovasti on yritetty vaikka millaisella tyylillä, mutta vasta jiaire sai sen oikein.
Aihe on jo aika vanha, joten et voi enää vastata siihen.