Avatar billede shj Nybegynder
23. september 1999 - 00:21 Der er 23 kommentarer og
2 løsninger

cin.getline springer en linie over

hej, håber ikke i er ved at værer alt for trætte af mine spørgsmål, men her er altså noget jeg overhovedet ikke forstår.
følgende streams skal indsamle data fra brugeren
cout<<setw(10)<<"indtats personens navn: "<<endl;
        cin.getline(navn,sizeof(navn));
        cout<<setw(10)<<"indtast Adresse"<<endl;
        cin.getline(adresse, sizeof(adresse));
Når jeg starter programmet skulle der stå indtast personens navn
$promt<<
men den springer navn over og går direkte til næste cout/cin adresse
jeg følger anvisningerne i min bog og har kigget i online doc for Borland c++ builder 4.0. Er der nogen der ved hvorfor?
Jeg kan poste hele sourcen hvis grundlaget her er for lidt!
Hilsen Simon
Avatar billede bjarke Nybegynder
23. september 1999 - 08:21 #1
setw(10) har vist ikke meget effekt, når du udskriver strenge på over 10 tegn!

Resten kan jeg ikke klare i hovedet:-(
Avatar billede bjarke Nybegynder
23. september 1999 - 08:22 #2
Men bare rolig hjælpen er på vej. Soepro må snart være der;-)
Avatar billede soepro Nybegynder
23. september 1999 - 08:53 #3
Udover at mine versioner af C++ (TC 3.0 og BC5.02) ikke vil kendes ved setw(), så vil jeg helt sikkert tro at det problem du løber i er, at længden af det du indtaster overstiger de 10 tegn der kan være i navn. getline(s, l, x) virker nemlig sådan at den ENTEN læser så mange tegn der er før x ELLER max l tegn. Hvis du så rent faktisk har indtastet flere, vil næste getline blot hente dem - fordi de er afsluttet med x (som normalt er enter). Hermed vil det for dig se ud som om nr. 2 getline springes over.

Jeg har kopieret din kodestump ind i et lille program (setw() udeladt), og får præcis det problem du beskriver, hvis jeg indtaster mere end 10 tegn i første omgang. Hvis jeg ikke gør - så virker det fint.

Jeg vil foreslå dig at ændre din logik til at bruge get i stf. getline - med get kan du vha. et lille loop selv bestemme hvor mange tegn der skal reageres på.

Generelt mener jeg ikke at nogen af standard funktionerne til indlæsning af tekststrenge, tal osv. fra skærmen er gode nok - der er simpelthen for lidt muligheder for at styre hvad der kan/må indtastes. Jeg endte i sin tid derfor med at lave min egen readkey() og readstr() rutiner - inkl. hotkey funktioner og styr på decimaler, fortegn osv. for numeriske værdier.
Avatar billede bjarke Nybegynder
23. september 1999 - 09:02 #4
soepro >> setw() definerer udskriftsbredden. Dvs, at der udskrives i et felt, på 10 tegn og det følgende udskrives derfra. Du kan bruge det, hvis du laver tabeludskrift f.eks. Men når du udskriver en streng på mere end de 10 tegn, så skriver man bare ud over feltet og funktionene får ingen betydning.
  Hvor får du i øvrigt de 10 tegn fra. De 10 i setw() har ikke noget med indlæsningen at gøre!
  I øvrigt er jeg enig - jeg har også selv været nødt til at lave mine egne indlæsningsrutiner - blandt andet for at kunne bruge funktionstaster.

simon >> prøv evt. at tømme strømmen efter indlæsning (det er nok noget med flush())
Avatar billede jinxed Nybegynder
23. september 1999 - 09:20 #5
soepro >> setw() ligger i iomanip.h og den virker fint i min bc (5.00&5.01)

simon >> sizeof(navn || adresse) er den ikke 1 ?
Avatar billede bjarke Nybegynder
23. september 1999 - 09:23 #6
jinxed >> ??? Hvis navn er defineret som char* navn[MAX], så er sizeof(navn) da MAX! (sizeof()!=strlen())
Avatar billede jinxed Nybegynder
23. september 1999 - 09:35 #7
bjarke >> hvorfor så ikke kalde getline med (navn, MAX) ? og der står ikke nogle steder i spm'et at han har erklæret dem sådan. Så slap lige af : )

Avatar billede bjarke Nybegynder
23. september 1999 - 09:41 #8
jinxed >> Måske fordi det er mere intuitivt? Næh, men hvordan skal han ellers have erklæret dem (ups, jeg mente char navn[MAX])? Det er svært at slappe af, når man sidder på arbejde og skal lave noget kedeligt, men beklager hvis jeg virker emsig (jeg er bare engageret;-)
Avatar billede jinxed Nybegynder
23. september 1999 - 10:05 #9
bjarke >> helt ok ; )
Avatar billede shj Nybegynder
23. september 1999 - 11:45 #10
uha, ser ud til jeg fik startet en større debat om i/o streams :-) jeg sidder her  og prøver at få soepro´s ide om at indlæse et tegn af gangen.
noget i retning af
while(!navn)//er jo et string array ikke?
{
navn=cin.get();
}
men det virker ikke
Avatar billede shj Nybegynder
23. september 1999 - 11:51 #11
sorry tror jeg har løsningen
for(int i=0;navn[i];i++)
{
navn[i]=cin.get();
}

Avatar billede shj Nybegynder
23. september 1999 - 11:54 #12
ok nu begynder det at blive trals, det virker ok med for løkken, men de springer bare endnu flere linier over, er der en af jer der har et brugbart eksempel.
Avatar billede bjarke Nybegynder
23. september 1999 - 11:58 #13
Ok, du kan lave en funktion over følgende skabelon, som kan udvides meget:

#define F1 <nummer>  // Kan ikke huske det i hovedet

int index=0;
do
{
tast=getch();
if(!tast)  // Hvis funktionstast med nul-byte
  switch(getch())
    {
    case F1: hjaelp();
            break;
    ...
    }
else
  navn[index++]=tast;
}
while(tast!=RETURN);
navn[index]='\0';

Og vupti, så har du din egen indlæsningsfunktion med mulighed for at bruge funktionstaster:-)
Avatar billede bjarke Nybegynder
23. september 1999 - 12:00 #14
Hov, det kunne vist egentlig kaldes et svar;-)

Forresten er der ikke en, der kan få ADMIN til at lave denne indtastningsboks lidt større? Det er simpelthen så irriterende at den er så lille:-(
Avatar billede soepro Nybegynder
23. september 1999 - 12:04 #15
shj >> Din for-løkke skal ændres til:

for(int i=0;navn[i] && i < sizeof(navn)-1;i++)
{
  navn[i]=cin.get();
}

Ellers får du puttet flere characterer ind i navn, ind der er plads til.
Avatar billede soepro Nybegynder
23. september 1999 - 12:09 #16
bjarke >> Meningen kendte jeg godt - jeg kunne bare ikke finde frem til header-filen.

shj >> Din løsning HAR jeg prøvet - men jeg kan ikke få den til at begrænse antallet af tegn, så brugeren kan indlæse - og dermed at jeg kun får læst den jeg kan aflevere i navn. På mig virker det somom cin bare læser derudaf indtil der bliver trykket på ENTER. get kommandoen aflevere derefter det ønskede antal tegn og gemmer resten til næste kald - og det er vel det du vil undgå ikke.
Avatar billede bjarke Nybegynder
23. september 1999 - 12:13 #17
soepro >> hvornår er navn[i]=0? Når man trykker retur, eller ctrl+z eller hva'?
Avatar billede bjarke Nybegynder
23. september 1999 - 12:21 #18
soepro >> nej, det kan man vist ikke (begrænse antallet af tegn der kan indtastes - heller ikke med scanf() eller nogen anden funktion - jo getch() selvfølgelig;-). Netop derfor vil det også være smartere at lave sin egen indlæsningsfunktion (som du jo allerede selv har skrevet). Men alt det vidste du vel godt(?)

simon >> selvfølgelig skal der lige en stopklods i ovenstående kode, så der ikke indlæses for mange tegn.

while ændres til: while( tast!=RETURN && index<sizeof(navn) );

Desuden skal man også lige kunne se det indtastede, så prøv at ændre getch() til getche()
Avatar billede shj Nybegynder
23. september 1999 - 12:23 #19
Hej igen! Jeg poster lige hel mit program, for det virker ikke rigtigt når jeg prøver det i foreslår. Ta jer ikke af den omgang spaghetti programmering det er blevet til ,det er et træningsprojekt jeg har gang i, og jeg er jo totalt newbie i c++ endnu
//#include <condefs.h>
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include <string.h>
#include <iomanip.h>
#include <conio.h>
int getch(void);
//---------------------------------------------------------------------------

//#pragma argsused
class ansat {
  public:
  ansat(char*,char*,char*,float,char*);
  ansat(void);
  void visansat(void);
  void soeg(void);
// private:
  char name[64];
  char adresse[64];
  char telefon[11];
  float gage;
  char cprnr[11];
};
ansat::ansat(char *navn,char *adresse,char *telefon,float gage,char *cpr)
{
  strcpy(ansat::name,navn);
  strcpy(ansat::adresse,adresse);
  strcpy(ansat::telefon,telefon);
  ansat::gage=gage;
  strcpy(ansat::cprnr,cpr);
}
void ansat::visansat(void)
{
char tast;
cout <<"medarbejder navn: "<<name<<endl;
cout <<"Adresse: "<<adresse<<endl;
cout <<"Telefon: "<<telefon<<endl;
cout <<"Gage: "<<gage<<endl;
cout <<"cpr nummer: "<<cprnr<<endl;
}

void main(void)
  {
  char navn[64];
  char adresse[64];
  char telefon[11];
  float gage = 0;
  char cprnr[11];
  char valg;
    cout <<setw(25)<<"Mit person program"<<endl;
    cout<<endl;
    cout<<"hvad vil du fortage dig tast 1 eller 2 eller 3"<<endl<<endl;
    cout <<"1 Indtaste ny person i registret"<<endl;
    cout <<"2 find en person i registret"<<endl;
    cout <<"3 Slette en person fra registret"<<endl;
    cin>>valg;

    if(valg=='1')
      {
    cout<<setw(10)<<"indtats personens navn: "<<endl;
    for(int i=0;navn[i] && i < sizeof(navn)-1;i++)
    {
      navn[i]=cin.get();
    }



    cout<<setw(10)<<"indtast Adresse"<<endl;
    for(int i=0;adresse[i] && i < sizeof(adresse)-1;i++)
    {
    adresse[i]=cin.get();
    }


    cout<<setw(10)<<"evt telefon nr."<<endl;
    for(int i=0;telefon[i] && i < sizeof(telefon)-1;i++)
    {
    telefon[i]=cin.get();
    }



          cout<<setw(10)<<"indtast gage"<<endl;
        cin>>gage;
        cout<<setw(10)<<"indtast person nr"<<endl;
        for(int i=0;cprnr[i] && i < sizeof(cprnr)-1;i++)
    {
        cprnr[i]=cin.get();
    }
        ansat medarbejder(navn,adresse,telefon,gage,cprnr);
        medarbejder.visansat();
        cout<<"vil du gemme disse oplysninger: (j/n)"<<endl;
        cin>>valg;
          if(valg=='j')
          {
            fstream ansatte;
            ansatte.open ("ansat.dat",ios::app);
            if(ansatte.fail())
            {
              cout <<"filen  kunne ikke aabnes"<<endl;
            }
            ansatte.write((char*)&medarbejder,sizeof(ansat));
            ansatte.close();
            }
}

    if(valg=='2')
  {
    ansat medarbejder(navn,adresse,telefon,gage,cprnr);

    ifstream search("ansat.dat",ios::in);
    cout <<"skriv navnet du vil soege efter: "<<endl;
    cin>>navn;
    while(!search.eof())
    {
        search.read((char*)&medarbejder, sizeof(ansat));
          if(strcmp(medarbejder.name,navn)==0)
          {
          cout <<medarbejder.name<<endl;
          cout <<medarbejder.adresse<<endl;
          cout <<medarbejder.telefon<<endl;
          cout <<medarbejder.gage<<endl;
          cout <<medarbejder.cprnr<<endl;
          }

          }



      }
}





Avatar billede bjarke Nybegynder
23. september 1999 - 12:34 #20
Puha, det har jeg ikke tid til lige nu, men et par hurtige bemærkninger:

1) Du behøver vist ikke iostream.h når du har fstream.h (?)
2) int getch(void). Drop den, du skal ikke selv definere funktioner med samme navn som eksisterende c-funktioner!
3) Brug valg=getch() (eller getche()) i stedet for cin >> valg, så slipper brugeren for at indtaste for mange tegn, samt at trykke return.
4) Læg de forskellige dele af programmet ud i hver deres funktion.
5) Saml så funktionskaldene i en switch-case sætning
6) Og smid til sidst det hele (menuen og switch-case sætningen med funktionskaldene ind i en do-while løkke).
7) Lav evt. indlæsningerne om til:

int index=0;
do
{
navn[index++]=getche();
}
while(tast!=RETURN && index<sizeof(navn));
navn[index]='\0';


Så skulle programmet blive noget mere letlæseligt og systematisk - og prøv så at se hvordan det virker efter det!
Avatar billede jinxed Nybegynder
23. september 1999 - 15:12 #21
bjarke >> helt enig. og klik på dit brugernavn og dine indstillinger der kan du ændre størrelsen på boksen ; )
Avatar billede shj Nybegynder
23. september 1999 - 15:35 #22
Hej !! jeg kan ikke få min compiler til at acceptere while(tast!=RETURN);
den broker sig over RETURN, er det defineret i en header fil eller skal jeg lave noget i stil med #define RETURN <char nummer>
og hvad er char nummeret
Hilsen Simon
Avatar billede bjarke Nybegynder
23. september 1999 - 15:47 #23
Ja, hvis jeg ikke tager helt fejl, så er det:

#define RETURN 13
Avatar billede shj Nybegynder
23. september 1999 - 16:12 #24
I burde jo have penge for at undervise mig i c++. Tak for hjælpen venner
Avatar billede bjarke Nybegynder
23. september 1999 - 16:14 #25
Ja tak;-) og velbekomme
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester