Według documentation dla scanf (nacisk moje):
Ciąg formatu składa się z białych znaków (każdy pojedynczy biały znak w ciągu formatu zużywa cały dostępny kolejne znaki odstępu od wejścia), wielobajtowe znaki spoza białych znaków, z wyjątkiem %
(każdy taki znak w ciągu znaków formatowania pochłania dokładnie jedną identyczną e wejście) i specyfikacje konwersji.
Zatem Twój format string %[^\n]\n
najpierw przeczytać (i przechowywać) dowolna liczba znaków nie-białych z wejścia (ze względu na %[^\n]
części), a następnie, z powodu następującego linią, czytać (i odrzucić) dowolna liczba białych znaków, takich jak spacje, tabulacje lub znaki nowej linii.
Dlatego, aby uczynić swoje wejście STOP scanf czyta, albo trzeba wpisać przynajmniej jeden non-białymi znak po znaku nowej linii, albo zorganizować strumień wejściowy do końca (na przykład przez naciśnięcie Ctrl + D w systemach Unix-ish).
Zamiast tego, aby twój kod działał zgodnie z oczekiwaniami, po prostu usuń ostatnie \n
z końca łańcucha formatu (jak już sugerował Umamahesh P).
Oczywiście spowoduje to pozostawienie znaku nowej linii w strumieniu wejściowym. Aby się go pozbyć (na wypadek, gdybyś chciał przeczytać inną linię później), możesz getc ze strumienia lub po prostu dołączyć %*c
(co oznacza "odczytaj jeden znak i odrzuć go") lub nawet %*1[\n]
(przeczytaj jeden znak nowej linii i odrzuć it) na końcu łańcucha formatu scanf.
Ps. Pamiętaj, że Twój kod ma kilka innych problemów. Na przykład, aby uniknąć błędów przepełnienia bufora, naprawdę powinieneś użyć %63[^\n]
zamiast %[^\n]
, aby ograniczyć liczbę znaków, które scanf odczyta do twojego bufora. (Limit musi być o jeden mniejszy niż rozmiar twojego bufora, ponieważ scanf będzie zawsze dołączał końcowy pusty znak).
Specyfikacja formatu %[
zawsze oczekuje co najmniej jednego pasującego znaku i zakończy się niepowodzeniem, jeśli żadna nie jest dostępny. Tak więc, jeśli naciśniesz enter natychmiast bez wpisywania czegokolwiek, twój scanf zawiedzie (cicho, ponieważ nie sprawdzasz wartości zwracanej) i pozostawi bufor wejściowy wypełniony losowymi śmieciami. Aby tego uniknąć, powinieneś a) sprawdzić wartość zwracaną przez scanf, b) ustawić input[0] = '\0'
przed wywołaniem scanf lub c) najlepiej oba.
Na koniec zwróć uwagę, że jeśli chcesz odczytywać linię wejściową po linii, to jest to o wiele łatwiejsze: łatwiej użyć po prostu fgets. Tak, jeśli nie chcesz, musisz usunąć sam znak końca linii (jeśli jest), ale jest to o wiele łatwiejsze i bezpieczniejsze niż próba użycia skanera do wykonania zadania, które nie jest przeznaczone dla:
#include <stdio.h>
#include <string.h>
void chomp(char *string) {
int len = strlen(string);
if (len > 0 && string[len-1] == '\n') string[len-1] = '\0';
}
int main(void)
{
char input[64];
printf("Enter some input: ");
fgets(input, sizeof(input), stdin);
chomp(input);
printf("You entered \"%s\".\n", input);
}
Nie zamieszczaj obrazów tekstu! – Olaf
to% [^ \ n], spróbuj tego –
@ user3121023 Dzięki, właśnie dlatego chciałem użyć '"% [^ \ n] \ n ". – ivan