Problem med cin m.m. (c++)
Har under kvällen skrivit ett program för att ta emot namn, telefonnummer och adress, för att sedan spara detta till en fil. Detta funkar utmärkt, så länge som inte någon av de extra funktionerna jag lagt in används. Problemet visar sig i att jag bara kan köra program ett "varv" innan saker börjar pucka ur, ska försöka förklara vad jag menar:
Värden skrivs in till en struct.
-
Värdena skrivs sedan ut på skärmen av funktionen output_person, följt av att frågan om de är korrekta ställs. Man kan då välja mellan att ändra seperata poster med funktionen modifier eller använda output_person igen, denna gång för att skriva informationen till filen.
-
Väljer man att använda modifier ges menyn för att välja post att ändra, och sedan är det tänkt att den ska ge möjligheten att skriva in nytt värde, vilket inte händer, programmet återgår istället omedelbart till den ursprungliga menyn.
-
Om värdena skrevs till filen dyker valet om man vill skriva in fler "personer" upp. Väljer man nej avbryts programmet (korrekt), men väljer man ja återgår man till starten, dock hoppar den över några (en?) variabler.
Det jag har problem med är alltså funktionen modifier och att det inte går att skriva till alla variabler när programmet utförs flera varv. Vill gärna veta vad jag gör fel och varför det är fel (är nybörjare, men vill lära mig).
Använder för övrigt gcc 3.4.6 med Slackware som system.
Koden (skrivet i emacs, därav formateringen):
#include <iostream>
#include <fstream>
namespace {
// storlekar på namnen
const int NA_SIZE = 40;
const int NU_SIZE = 18;
const int AD_SIZE = 100;
struct info {
char namn[NA_SIZE];
char nummer[NU_SIZE];
char adress[AD_SIZE];
};
}
void output_person(std::ostream & output, const info *person);
void modifier(info *person);
int main() {
using std::cout;
using std::cin;
using std::endl;
using std::ofstream;
info *person;
ofstream outFile;
char filename[] = "telefonnummer.txt";
while (true) {
// fil öppnas, kan skrivas till och detta läggs till på slutet i filen
outFile.open(filename, ofstream::out | ofstream::app);
// kontrollerar om filen kunde öppnas
if (!outFile.is_open()) {
cout << "Kunde inte öppna filen " << filename << endl;
exit(EXIT_FAILURE);
}
person = new info; // skapa plats för infon
// ta emot info
cout << "Namn: ";
cin.getline(person->namn, NA_SIZE);
cout << "Telefonnummer: ";
cin.getline(person->nummer, NU_SIZE);
cout << "Adress: ";
cin.getline(person->adress, AD_SIZE);
// kontrollera att det inskrivna är korrekt
modifier(person);
cout << endl << "Skriver till " << filename << "...\n";
output_person(outFile, person); // skriver till filen
// röja upp
delete person;
outFile.close();
char quitchoice;
cout << "Lägga till fler personer (J/N)? ";
cin >> quitchoice;
// eliminerar newline, som annars puckar ur getline()
while(cin.peek() != '\n') {
cin.ignore();
cin.ignore();
}
if (quitchoice != 'J')
return 0;
}
}
// funktion för att skriva ut infon, till cout eller outFile
void output_person(std::ostream & output, const info *person) {
using std::endl;
output << "Namn: " << person->namn << endl
<< "Telefonnummer: " << person->nummer << endl
<< "Adress: " << person->adress << endl;
}
// kontrollerar att inputen är korrekt, moddar den annars
void modifier(info *person) {
using std::cout;
using std::cin;
using std::endl;
char val = '\0';
output_person(cout, person);
// kräv ett riktigt svar
while (val != 'J' && val != 'N') {
cout << endl << "Ser allt korrekt ut (J/N)? ";
cin >> val;
while(cin.peek() != '\n') {
cin.ignore();
cin.ignore();
}
}
if (val == 'N') {
while( val != 'Q') {
cout << endl;
output_person(cout, person);
cout << endl << "Vilket är fel? " << endl
<< "Namnet (N)" << endl
<< "Telefonnummret (T)" << endl
<< "Adressen (A)" << endl
<< "Inget (Q)" << endl
<< "Felet finns i (N/T/A/Q): ";
cin >> val;
while(cin.peek() != '\n') {
cin.ignore();
cin.ignore();
}
switch (val) {
case 'N':
cout << "Namn: ";
cin.getline(person->namn, NA_SIZE);
break;
case 'T':
cout << "Telefonnummer: ";
cin.getline(person->nummer, NU_SIZE);
break;
case 'A':
cout << "Adress: ";
cin.getline(person->adress, AD_SIZE);
break;
case 'Q':
break;
default:
cout << "Felaktigt val";
}
}
}
}
EDIT: Uppdaterade koden till den slutgiltiga
Stationär: Intel-baserad, Arch + KDE
Bärbar: Dell XPS 13, Arch + KDE