2016-06-07 20 views
3

IC++ wie Strom bis zum Ende der Zeile lesen

Kugel 3 2 3 4
pyramiden 2 3 4 12 3 5 6 7 3 2 4 1 2 3 eine Eingabe, wie dies aus Datei lesen möchte
Rechteck 2 3 4 1 9 12

ich so etwas wie dieses

char name[64]; 
int arr[12]; 
ifstream file (..); 
while(file) 
{ 
file >> name; 
    while(//reach end of line) 
     file >> arr[i] 
} 

tun möchten wie Sie ich weiß nicht, wie man sehen kann Es werden ganze Zahlen eingegeben, deshalb möchte ich bei der neuen Zeile anhalten. Ich habe es mit getline gemacht, und dann die Linie getrennt, aber sie sagten mir, dass es nur mit >> Operator gemacht werden kann.

Hinweis: Ich kann std::string oder std::vector nicht verwenden.

+1

Lookup ‚C++ CSV zu analysieren‘ (und haben einen Raum als Trennzeichen) –

+0

@ DieterLücking Ich habe für eine lange Zeit zu lesen, und konnte es nicht TU es. Kannst du mir zeigen? – Gigata

+0

* Ich weiß nicht, wie viele ganze Zahlen eingegeben werden * - * Hinweis: Ich kann nicht std :: string oder std :: vector * - Was ist, wenn es mehr als 12 ganze Zahlen in dieser Zeile gibt? – PaulMcKenzie

Antwort

3

Die einfache Version ist die Verwendung eines Manipulators ähnlich std::ws, aber statt alle Whitespace-Einstellung std::ios_base::failbit zu überspringen, wenn ein Newline auftritt. Dieser Manipulator würde dann verwendet werden, um Whitespace implizit zu überspringen, wobei Whitespace außer Newlines übersprungen wird. Zum Beispiel (ist der Code nicht Test, aber ich denke, so etwas wie dies mit dem Bugs und Kompilierungsfehlern sollen entfernt arbeiten):

std::istream& my_ws(std::istream& in) { 
    std::istream::sentry kerberos(in); 

    while (isspace(in.peek())) { 
     if (in.get() == '\n') { 
      in.setstate(std::ios_base::failbit); 
     } 
    } 
    return in; 
} 
// ... 
char name[64]; 
int array[12]; 
while (in >> std::setw(sizeof(name)) >> name) { // see (*) below 
    int* it = std::begin(array), end = std::end(array); 
    while (it != end && in >> my_ws >> *it) { 
     ++it; 
    } 
    if (it != end && in) { deal_with_the_array_being_full(); } 
    else { 
     do_something_with_the_data(std::begin(array), it); 
     if (!in.eof()) { in.clear(); } 
    } 
} 

Meine persönliche Vermutung ist, dass die Zuordnung zum Lesen der Werte in char Arrays gefragt, gefolgt von Umwandlung sie unter Verwendung atoi() oder strol(). Ich denke, das wäre eine langweilige Lösung für die Übung.

(*) Nie, nicht einmal in exmaple Code, verwenden Sie den formatierte Eingabe-Operator mit einem char Array arrayohne auch die maximal zulässige Größe einstellen! Die Größe kann durch Einstellen der width() des Streams eingestellt werden, z. B. unter Verwendung des Manipulators std::setw(sizeof(array)). Wenn width()0 ist, wenn der formatierte Eingabeoperator mit einem char-Array verwendet wird, wird eine beliebige Anzahl von Nicht-Leerzeichen gelesen. Dies kann leicht Überlauf das Array und ein Sicherheitsproblem werden! Im Wesentlichen ist dies die C++ - Schreibweise von gets() von C (die jetzt sowohl aus der C- als auch der C++ - Standardbibliothek entfernt wird).

1

Ich nehme an, dass Sie peek Methode verwenden können:

while (file) 
{ 
    file >> name; 
    int i = 0; 
    while(file.peek() != '\n' && file.peek() != EOF) { 
     file >> arr[i++]; 
    } 
} 
+0

Was passiert, wenn zwischen den Werten mehrere Leerzeichen stehen? –

+0

@ DietmarKühl Hmm, aber was ist das Problem mit mehreren Räumen? –

+0

Das Problem ist, dass der Newline eine vorangestellt werden kann und Ihr Test für die Newline nicht ausgelöst wird. –