2012-05-04 12 views
6

Uczę się C++ i otrzymałem projekt wysłania trójkąta pascalowego do wyjścia (po n-rzędach obliczeń). Uzyskanie wyniku takiego jak ten, zapisanego w strumieniu "bufora" strumieniaUżywanie strumienia łańcuchowego do wcięcia/wyśrodkowania wyjścia

1 
1 1 
1 2 1 
1 3 3 1 

Ale co chcę jest raczej

1 
    1 1 
    1 2 1 
1 3 3 1 

Mój pomysł był następujący: obliczyć różnicę ostatniej linii i bieżącej długości linii (wiem, że ostatni z nich jest najdłuższy). Następnie wstaw każdy rząd za pomocą spacji (połowa różnicy długości linii). Mój problem jest teraz:

  • nie dostać prace jak getline, ani w jaki sposób mogę wyodrębnić specyficzne (-> ostatnia) Linia
  • nie wiem i nie mógł znaleźć sposobu edytowania jednego konkretna linia w strumieniu łańcuchowym

Jakoś mam wrażenie, że nie jestem na najlepszej drodze, używając strumienia stringów.

Jest to raczej typowe pytanie: jak rozwiązać ten problem, a jeśli to możliwe, z łańcuchami - jak?

+1

http://www.cplusplus.com/reference/iostream/manipulators/setw/ Spójrz na to – v01d

+0

Tylko dla jasności, czy obliczasz wartości własne i drukowanie? A może analizujesz je, a następnie drukujesz? – Benj

+0

Sam je obliczam, zobaczę setw, wydaje mi się, że to fajny sposób :-) – AnatraIlDuck

Odpowiedz

2

Aby dowiedzieć wcięcie pierwszej linii , musisz znać liczbę linii na wejściu. Dlatego musisz najpierw przeczytać wszystkie dane wejściowe. Wybrałem użycie wektora do zapisania wartości dla wygody funkcji .size(), która da całkowitą liczbę linii po wczytaniu we wszystkich wejściach.

#include<iostream> 
#include<sstream> 
#include<vector> 
#include<iomanip> // For setw 
using namespace std; 
int main() 
{ 
    stringstream ss; 
    vector<string> lines; 
    string s; 

    //Read all of the lines into a vector 
    while(getline(cin,s)) 
    lines.push_back(s); 

    // setw() - sets the width of the line being output 
    // right - specifies that the output should be right justified 
    for(int i=0,sz=lines.size();i<sz;++i) 
    ss << setw((sz - i) + lines[i].length()) << right << lines[i] << endl; 

    cout << ss.str(); 
    return 0; 
} 

W tym przykładzie używam setw, aby ustawić szerokość linii na wyrównanie do prawej. Wypełnienie po lewej stronie napisu jest podawane przez (sz - i), gdzie sz jest całkowitą liczbą linii, a i jest bieżącą linią. Dlatego każda kolejna linia ma 1 mniej miejsca po lewej stronie.

Następnie należy dodać oryginalny rozmiar linii (linie [i] .length()), w przeciwnym razie linia nie będzie zawierała wystarczająco dużej przestrzeni, aby wynikowy ciąg miał prawidłowe wypełnienie po lewej stronie bok.

setw((sz - i) + lines[i].length()) 

Mam nadzieję, że to pomoże!

0

Jeśli masz dostęp do kodu, który zapisuje początkowe wyjście, a jeśli znasz numer linii N piszesz, można po prostu zrobić:

for(int i = 0; i < N; ++i) { 
    for(int j = 0; j < N - 1 - i; ++j) 
     sstr << " "; // write N - 1 - i spaces, no spaces for i == N. 
    // now write your numbers the way you currently do 
} 
+1

i wątpię, że zadziała, gdy N wzrośnie i pojawią się cyfry dwucyfrowe. Czy to będzie? – nims

+1

@nims Oczywiście, musisz obliczyć 'width = max (wybierz (N, k)% 10', aby uzyskać liczbę cyfr i wpisz (N - 1 - i) * szerokość białych znaków.Chodzi mi po prostu o to, że łatwiej jest łączyć formatowanie z obliczeniami, niż formatować wyniki po obliczeniach. – TemplateRex

+0

jakoś byłoby mi ładniej najpierw obliczyć wartości, a następnie sformatować wyjście ... – AnatraIlDuck

Powiązane problemy