Permalänk
Medlem

Läsa in text i c++

Jag har problem med att läs in text till mitt c++ program.

Mitt första försök var att jag gjorde
cin >> text;
Då fick jag bara med det första ordet, vilket inte var vad jag var ute efter. Jag vill kunna läsa in mycket text.

Då hittade jag att det fanns getline, och testade
getline(cin,text);
och testade även
getline(cin,text,'\n');

Båda dessa uppförde sig som att kodraden inte ens fanns, utan hoppade förbi och väntade inte alls på någon input.

Då började jag skriva en loop själv

string str; while(cin >> str){ if(str == "</end>") break; text += str + " "; }

Men detta känns inte som en bra lösning. För det första så missar jag whitespace och behandlar alla som mellanslag. Och sen får den inte med radbrytningar heller. Finns det något enkelt sätt att lösa detta så att jag får in texten så som jag skriver exakt i en sträng?

Radbrytningar är kanske inte jätteviktigt, utan om man kan få den att läsa in texten som skrivs inklusive whitespace så är det kanske nog. Men radbrytningar hade också varit bra.

Visa signatur

Du är min fiende tills motsatsen är bevisad, och bevisbördan ligger hos dig.

Permalänk
Hedersmedlem

Matar du in på något annat sätt än med getline()? I så fall kan till exempel radbrytningar bli kvar i bufferten och störa senare användning av till exempel getline. Testa om cin.ignore() hjälper.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Elgot
Matar du in på något annat sätt än med getline()? I så fall kan till exempel radbrytningar bli kvar i bufferten och störa senare användning av till exempel getline. Testa om cin.ignore() hjälper.

Det fungerade med cin.ignore(), måste vara att det låg kvar skräp från föregående cin.

Det hade varit kul att få radbrytningar att fungera också, problemet är att den enda ide jag har är att man lägger in så att den lyssnar på en endtag och avslutar inmatningen då. Men det känns inte så kul. Skulle det gå att göra så att den lyssnar på någon speciell knapptryckning, typ ctrl + b eller något? Jag är inte ute efter någon komplicerad lösning här, utan om det blir för svårt och för många rader kod så skiter jag nog hellre i det.

Visa signatur

Du är min fiende tills motsatsen är bevisad, och bevisbördan ligger hos dig.

Permalänk
Medlem

En variant som du kan köra om du läser från fil är att skippa iostream och köra cstdio (fopen, fseek, ftell, fread, fclose) för att läsa all data i ett chunk. Går ju att göra mot stdin som file handle också.

Visa signatur

void@qnet
teeworlds, stålverk80, evil schemer, c, c++
Languages shape the way we think, or don't.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av jdv
En variant som du kan köra om du läser från fil är att skippa iostream och köra cstdio (fopen, fseek, ftell, fread, fclose) för att läsa all data i ett chunk. Går ju att göra mot stdin som file handle också.

Läser direkt från tangentbordet.

Visa signatur

Du är min fiende tills motsatsen är bevisad, och bevisbördan ligger hos dig.

Permalänk
Hedersmedlem
Citat:

Ursprungligen inskrivet av pSyChO
Skulle det gå att göra så att den lyssnar på någon speciell knapptryckning, typ ctrl + b eller något?

Ctrl + D är väl annars den vanliga kombinationen; testa!

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av pSyChO
Läser direkt från tangentbordet.

fopen(stdin, 'r');

Sen kan du läsa från tangentbordet som om det vore en vanlig fil.

Permalänk
Medlem

Jag googlade lite och hittade lite om hur man borde kunna göra

while(!cin.eof()){ getline(cin,str); text += str; text += '\n'; }

Ctrl+D ska tydligen ge eof. Dock lyckades jag inte få detta att fungera. Är tanken rätt? Jag läste nämligen även att det är olika på windows och linux datorer hur Ctrl+D tolkas, och just nu sitter jag på en windowsdator och kan ju då inte testa riktigt

Visa signatur

Du är min fiende tills motsatsen är bevisad, och bevisbördan ligger hos dig.

Permalänk
Hedersmedlem

Ctrl + z är det nog som gäller för windows.

while(getline(cin, str)) { text += str; text += '\n'; }

Permalänk
Medlem

Alla försökt jag har gjort (inklusive ditt) får programmet att krascha och spotta ut en massa skräp på skärmen när man försker med antingen ctrl+D eller ctrl + Z

Visa signatur

Du är min fiende tills motsatsen är bevisad, och bevisbördan ligger hos dig.

Permalänk
Hedersmedlem
Citat:

Ursprungligen inskrivet av pSyChO
Alla försökt jag har gjort (inklusive ditt) får programmet att krascha och spotta ut en massa skräp på skärmen när man försker med antingen ctrl+D eller ctrl + Z

Är det där den kraschar? Observera att du måste anropa cin.clear() innan du kan läsa från den normalt igen efter att ha skickat filslutstecknet.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Elgot
Är det där den kraschar? Observera att du måste anropa cin.clear() innan du kan läsa från den normalt igen efter att ha skickat filslutstecknet.

Där satt den, tack
Det gick sönder direkt när jag tryckte ctrl + D innan, men när jag la till clrear efteråt så löste det sig

Visa signatur

Du är min fiende tills motsatsen är bevisad, och bevisbördan ligger hos dig.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av jdv
En variant som du kan köra om du läser från fil är att skippa iostream och köra cstdio (fopen, fseek, ftell, fread, fclose) för att läsa all data i ett chunk. Går ju att göra mot stdin som file handle också.

Detta går även med iostreams. Det passar även bra tillsammans med std::vector för att slippa släppa resurser manuellt.

std::string read_file(const std::string &filename) { std::ifstream file(filename.c_str()); file.seekg(0, std::ios::end); int file_size = file.tellg(); file.seekg(0, std::ios::beg); std::vector<char> data(file_size); file.read(&data[0], file_size); return std::string(data.begin(), data.end()); }

Citat:

Ursprungligen inskrivet av You

fopen(stdin, 'r');

Sen kan du läsa från tangentbordet som om det vore en vanlig fil.

stdin är en FILE*, så man behöver inte öppna en ny för att använda den som en vanlig fil.

Visa signatur

Vill du ha svar? Citera mig gärna.

Permalänk
Hedersmedlem

Iteratorvarianten är ju också förförisk i sin enkelhet:

vector<char> v; cin >> noskipws; copy(istream_iterator<char>(cin), 0, back_inserter(v));