2011-11-17 8 views
15

Mam bufor, który otrzymuję przez port szeregowy. Kiedy otrzymuję określony znak, wiem, że nadszedł pełny wiersz i chcę go wydrukować za pomocą metody printf. Ale każda linia ma inną wartość długości, a kiedy po prostu iść z:Printf bufor o wartości podanej w C

printf("%s", buffer); 

ja Drukowanie linii plus dodatkowe znaki należące do dawnej linii (jeśli był dłuższy niż obecnie).

Czytam , że jest możliwe, przynajmniej w C++, aby powiedzieć, ile znaków chcesz przeczytać, biorąc pod uwagę %s, ale nie ma przykładów i nie wiem jak to zrobić w C. Każda pomoc ?

EDYCJA: Idealna. Więc mam trzy rozwiązania: - drukowanie char przez char z for pętli - używając znaku kończącego - lub za pomocą *

pytanie brzmi:. Która z nich jest szybszy? Ponieważ pracuję nad mikroprocesorem PIC i chcę, żeby to się stało tak szybko jak to możliwe

+2

Kiedy już otrzymała to * "pewną postacią" * i zostały dołączone go 'buffer', dołącz znak null (' \ 0'), jak również. To "mówi" 'sprintf()' kiedy przestać drukować znaki. –

Odpowiedz

22

Łańcuch, który masz, nie jest zakończony znakiem NUL, więc printf (i każda inna funkcja ciągu C) nie może określić jego długości, dlatego będzie nadal zapisywał postacie, które tam znajdzie, dopóki nie natknie się na znak null, który się tam znajduje.

celu rozwiązania problemu możesz:

  • korzystanie fwrite nad stdout:

    fwrite(buffer, buffer_length, 1, stdout); 
    

    To działa, ponieważ fwrite nie jest uważany za drukowania tylko strun, ale każdy rodzaj danych, tak nie szuka znaku końcowego o wartości zerowej, ale akceptuje długość danych, które mają być zapisane jako parametr;

  • null wypowiedzieć bufor ręcznie przed drukowaniem:

    buffer[buffer_length]=0; 
    printf("%s", buffer); /* or, slightly more efficient: fputs(buffer, stdout); */ 
    

    To może być lepszy pomysł, jeśli masz do zrobienia jakiegokolwiek innego przetwarzania ciągów nad buffer, że teraz będzie zakończony zerem, a więc do opanowania przez normalne funkcje przetwarzania ciągów znaków C.

+0

Jestem zaskoczony, że odpowiedzi na duplikaty tego pytania SO nie obejmują tej metody, ale sugerują tylko "za" pętle ... – Alex

1

Po zidentyfikowaniu koniec linii, należy dołączyć '\0' znak na końcu bufora przed wysłaniem go do printf.

+0

Ktoś, kto ma obniżony poziom, chce wyjaśnić, dlaczego mogę poprawić moją odpowiedź? –

+0

Powinieneś powiedzieć, co OP zrobił źle, oprócz tego, jak to poprawić. – Alex

37

Można dodać znak null po swojej postaci wypowiedzenia, a printf będzie działać, lub można dodać '.*' w instrukcji printf oraz zapewnienie długości

printf("%.*s",len,buf); 

w C++ cię prawdopodobnie używać std :: string i std :: cout zamiast, jak to:

std::cout << std::string(buf,len); 

Jeśli chcesz to najszybsza prędkość i formatowanie nie - użyj

fwrite(buf,1,len,stdout); 
+0

ładny, nie wiedziałem tego – Ben

+0

Idealny. Tak więc mam trzy rozwiązania: drukowanie char przez char z pętlą for, używanie znaku kończącego lub używanie. * QUESTION IS: który z nich jest szybszy? Ponieważ pracuję nad mikroprocesorem PIC i chcę, żeby to się stało szybko –

+0

@RomanRdgz: moje przypuszczenia: 'fwrite' lub null-terminator +' fputs' powinny być najszybsze, po którym następuje terminacja zerowa + 'printf' (może być wolniejszy ponieważ może być konieczne sparsowanie ciągu formatów, chyba że kompilator jest bardzo inteligentny), następnie 'printf' z'. * '(z pewnością musi przeanalizować ciąg formatu) i ostatni znak wydruku char (prawdopodobnie najwolniejszy, ze względu na wszystkie wywołania funkcji - to jednak może być wstawione). –

3

Możesz umieścić NUL (0x0) w buforze po odebraniu ostatniego znaku.

buffer[i] = 0;

Powiązane problemy