przekierowanie strumieni.

przekierowanie strumieni.
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 8 lat
  • Postów:199
0
Kopiuj
#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char* argv[]) {


    (argc > 2 ? ofstream(argv[2], ios::out | ios::binary )  : cout )
    <<
    (argc > 1 ? ifstream(argv[1], ios::in | ios::binary ) : cin ).rdbuf();


    return 0;
}

Co w tym kodzie jest nie tak, że rzuca błędem?

edytowany 1x, ostatnio: mielony
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
1

ofstream(argv[2], ios::out | ios::binary) ma tu typ const ofstream&

Kopiuj
   ifstream fin;
   ofstream fout;
   if(argc>1)
     {
      fin.open(argv[1]);
      fatal(!fin,"Nie da sie otworzyc podanego pliku wejscia");
      cin.rdbuf(fin.rdbuf());
     }
   if(argc>2)
     {
      fout.open(argv[2]);
      fatal(!fin,"Nie da sie stworzyc podanego pliku wyjscia");
      cout.rdbuf(fout.rdbuf());
     }

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 8 lat
  • Postów:199
0

to jak poprawić mój kod?

kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 dni
  • Lokalizacja:Szczecin
5

Nie wiem czy da się to zrobić w prosty sposób. (da się, użyć basic_Xstream::rdbuf, za przykładem @_13th_Dragon​a)

Co w tym kodzie jest nie tak, że rzuca błędem?

Nie jestem 100% pewien tego co piszę, ale to wydaje mi się sensowne.
Jak działa operator ternarny, a konkretniej, jak jest ustalony jego wynikowy typ? To jest opisane dokładniej w § 5.16 [expr.cond]/3:

N3797 napisał(a)

if the second and third operand have different types and either has (possibly cv-qualified) class type, or if both are glvalues of the same value category and the same type except for cv-qualification, an attempt is made to convert each of those operands to the type of the other. The process for determining whether an operand expression E1 of type T1 can be converted to match an operand expression E2 of type T2 is defined as follows:
— If E2 is an lvalue: E1 can be converted to match E2 if E1 can be implicitly converted (Clause 4) to the type “lvalue reference to T2”, subject to the constraint that in the conversion the reference must bind directly (8.5.3) to an lvalue.
— If E2 is an xvalue: E1 can be converted to match E2 if E1 can be implicitly converted to the type “rvalue reference to T2”, subject to the constraint that the reference must bind directly.
— If E2 is a prvalue or if neither of the conversions above can be done and at least one of the operands has (possibly cv-qualified) class type:
— if E1 and E2 have class type, and the underlying class types are the same or one is a base class of the other: E1 can be converted to match E2 if the class of T2 is the same type as, or a base class of, the class of T1, and the cv-qualification of T2 is the same cv-qualification as, or a greater cv-qualification than, the cv-qualification of T1. If the conversion is applied, E1 is changed to a prvalue of type T2 by copy-initializing a temporary of type T2 from E1 and using that temporary as the converted operand.
— Otherwise (i.e., if E1 or E2 has a nonclass type, or if they both have class types but the underlying classes are not either the same or one a base class of the other): E1 can be converted to match E2 if E1 can be implicitly converted to the type that expression E2 would have if E2 were converted to a prvalue (or the type it has, if E2 is a prvalue).

ostream(argv[2]) to prvalue, a cin to lvalue. Kompilator próbuje przekonwertować jedno w drugie, ale nie może, bo basic_ostream jest niekopiowalny, a konstruktor przenoszący jest protected.

Możesz to obejść w ohydny sposób z leakami: http://melpon.org/wandbox/permlink/Wkezq9jg7layMydV

Kopiuj
#include <iostream>
#include <fstream>
 
using namespace std;
 
int main(int argc, char* argv[])
{
    ostream& o = argc > 2 ? *new ofstream(argv[2], ios::out | ios::binary )  : cout;
    istream& i = argc > 1 ? *new ifstream(argv[1], ios::in | ios::binary ) : cin;
    
    o << i.rdbuf();
 
    return 0;
}

co potem możesz upięknić¹ do: http://melpon.org/wandbox/permlink/199NAbuuc42g4IAI

Kopiuj
#include <iostream>
#include <fstream>
#include <memory>
 
using namespace std;
 
int main(int argc, char* argv[])
{
    auto o = argc > 2 ? make_shared<ofstream>(argv[2], ios::out | ios::binary )  : shared_ptr<ostream>(&cout,[](void*){});
    auto i = argc > 1 ? make_shared<ifstream>(argv[1], ios::in | ios::binary ) : shared_ptr<istream>(&cin,[](void*){});
    
    *o << i->rdbuf();
 
    return 0;
}

Swoją drogą ostatnio robiłem coś podobnego w D i tam to się odbyło bez problemów:

Kopiuj
auto inFile = args.length > 2 ? File(args[2], a == Action.Decode ? "r" : "rb") : stdin;
auto outFile = args.length > 3 ? File(args[3], a == Action.Decode ? "wb" : "w") : stdout;

¹ dla pewnych definicji piękna.


edytowany 4x, ostatnio: kq
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
1

Właściwie to już pokazałem ale widzę że nawet @kq tego nie zauważył :D
Może być dwa warianty:
1.

Kopiuj
   cout.rdbuf(argc>2?ofstream(argv[2],ios::out|ios::binary).rdbuf():cout.rdbuf());
   cin.rdbuf(argc>1?ifstream(argv[1],ios::in|ios::binary).rdbuf():cin.rdbuf());
   cout<<cin.rdbuf();
Kopiuj
   cout.rdbuf(argc>2?ofstream(argv[2],ios::out|ios::binary).rdbuf():cout.rdbuf());
   cout<<(argc>1?ifstream(argv[1],ios::in|ios::binary).rdbuf():cin.rdbuf());

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
kq
Nigdy nie używałem tego przeładowania rdbuf, więc nie byłem pewien, czy Twoja odpowiedź jest w 100% na temat :P Codziennie można się czegoś nauczyć.
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 8 lat
  • Postów:199
0

prvalue to coś o czymś nie wiem czy tylko literówka?
Wiem co to rvalue i lvalue, ale co to jest Prvalue? I tak samo Plvalue?

Endrju
Panie, jest lvalue, prvalue, rvalue, xvalue i glvalue. :-D (Serio, C++ jest "trochę" skomplikowany)
MI
a ja myślałem, że nie każdy wie o lvaluve ;)
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 8 lat
  • Postów:199
0

basic_ostream jest niekopiowalny

Co to dokładniej znaczy? Konstruktor kopiujący jest sprywatyzowany :D ?

kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 dni
  • Lokalizacja:Szczecin
1

To nie jest literówka: http://stackoverflow.com/questions/3601602/what-are-rvalues-lvalues-xvalues-glvalues-and-prvalues

niekopiowalny: http://en.cppreference.com/w/cpp/io/basic_ostream/basic_ostream Przeładowanie (2) - = delete oznacza celowy brak implementacji danej funkcji. Nie ma jej i nie można jej używać.


edytowany 1x, ostatnio: kq
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 8 lat
  • Postów:199
0

rozumiem, że w C++03 jak nie chcieliśmy umożliwiać używania metody to prywatyzowaliśmy ją- nie było innej możliwości. Skądinąd nie było to najlepsze rozwiązanie.
W C++11 wprowadzili taką możliwość, żeby określić, których metod celowo nie chcemy. Problem dotyczy tylko takich metod, które są domyślnie? Np. właśnie domyślny konstruktor kopiujący? No bo jeżeli nie chcemy czegoś to normalnie nie definiujemy tego :D
Dobrze myślę?

edytowany 1x, ostatnio: mielony
Endrju
  • Rejestracja:około 22 lata
  • Ostatnio:ponad rok
3

@mielony: Możesz usunąć (= delete) każdą funkcję. Nawet "zwykłe" funkcje - tzn. nie będące składnikami klas. To może się przydać, kiedy chcesz zabronić niejawnej konwersji argumentów:

Kopiuj
void funkcja_dla_double(float arg) = delete;
void funkcja_dla_double(double arg) {
...
}

funkcja_dla_double(1.0f); // błąd kompilacji

Taką funkcję można wywołać tylko dla argumentu o typie double.


"(...) otherwise, the behavior is undefined".
edytowany 1x, ostatnio: Endrju
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 8 lat
  • Postów:199
0

ok, inaczej by zaszzła niejawna konwersja?
Czy nie jest tak, że C++ zaczyna gonić swój ogon?
Zamiast powiedzieć co chcemy to musimy jeszcze informować czego nie chcemy. Trochę to dziwne.

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0

Nie jest dziwne, zobacz przykład od @Endrju, akurat jest dziwne że nie chcemy mieć możliwości przekazania float.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)