Odczytywanie ciągu Z Wejścia ze znakiem spacji? [duplikat]

to pytanie ma już odpowiedzi tutaj : Jak zezwolić na Wprowadzanie spacji za pomocą scanf? (11 odpowiedzi) Zamknięty 2 lata temu .

Używam Ubuntu i używam również Geany i CodeBlock jako mojego IDE. Próbuję odczytać łańcuch znaków (np. "Barack Obama") i umieścić go w zmiennej:

#include <stdio.h>

int main(void)
{
    char name[100];

    printf("Enter your name: ");
    scanf("%s", name);
    printf("Your Name is: %s", name);

    return 0;
}

Wyjście:

Enter your name: Barack Obama
Your Name is: Barack

Jak sprawić, by program odczytał całą nazwę?

Author: alk, 2011-06-08

14 answers

Użycie:

fgets (name, 100, stdin);

100 Maksymalna długość bufora. Powinieneś dostosować go zgodnie z potrzebami.

Użycie:

scanf ("%[^\n]%*c", name);

[] jest znakiem scanset. [^\n] mówi, że podczas gdy wejście jest , a nie, nowa linia ('\n') przyjmuje wejście. Następnie %*c odczytuje znak nowej linii z bufora wejściowego (który nie jest odczytywany), a * wskazuje, że ten odczyt w wejściu jest odrzucany (eliminacja przypisania), ponieważ nie jest potrzebny, a ta nowa linia w buforze wejściowym bufor nie tworzy żadnego problemu dla kolejnych wejść, które możesz wziąć.

Przeczytaj tutaj o operatorach scanset i assignment suppression.

Uwaga Możesz również użyć gets ale ....

Nigdy nie używaj gets(). Ponieważ nie jest możliwe określenie bez uprzedniej znajomości danych ile znaków gets () odczyta i ponieważ gets() będzie nadal przechowywać znaki poza końcem bufora, jest to niezwykle niebezpieczne dla użyj. Został on użyty do złamania bezpieczeństwa komputera. Zamiast tego użyj fgets().

 188
Author: phoxis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-17 02:42:58

Spróbuj tego:

scanf("%[^\n]s",name);

\n po prostu ustawia ogranicznik dla zeskanowanego łańcucha.

 20
Author: Sridhar Iyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-17 02:38:56

Oto przykład jak można uzyskać dane wejściowe zawierające spacje za pomocą funkcji fgets.

#include <stdio.h>

int main()
{
    char name[100];
    printf("Enter your name: ");
    fgets(name, 100, stdin); 
    printf("Your Name is: %s", name);
    return 0;
}
 7
Author: kyle k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-02 00:52:55
scanf(" %[^\t\n]s",&str);

str jest zmienną, z której otrzymujesz ciąg znaków.

 6
Author: animesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-28 22:29:48

Uwaga: Podczas używania fgets (), ostatnim znakiem w tablicy będzie '\N' w czasie, gdy używasz fgets () dla małych wejść w CLI (interpreter wiersza poleceń), gdy kończysz łańcuch z 'Enter'. Więc po wydrukowaniu ciągu kompilator zawsze przejdzie do następnej linii podczas drukowania ciągu. Jeśli chcesz, aby łańcuch wejściowy miał null zakończony łańcuch jak zachowanie, użyj tego prostego hack.

#include<stdio.h>
int main()
{
 int i,size;
 char a[100];
 fgets(a,100,stdin);;
 size = strlen(a);
 a[size-1]='\0';

return 0;
}

Aktualizacja: Aktualizacja z Pomocą innych użytkowników.

 2
Author: Ritesh Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-31 13:16:00

Prawidłowa odpowiedź brzmi:

#include <stdio.h>

int main(void)
{
    char name[100];

    printf("Enter your name: ");
    // pay attention to the space in front of the %
    //that do all the trick
    scanf(" %[^\n]s", name);
    printf("Your Name is: %s", name);

    return 0;
}

Ta SPACJA przed % jest bardzo ważna, ponieważ jeśli masz w swoim programie jeszcze kilka scanf powiedzmy, że masz 1 scanf o wartości całkowitej i inny scanf o podwójnej wartości... gdy dotrzesz do scanf dla Twojego znaku (string name), to polecenie zostanie pominięte i nie możesz wprowadzić dla niego wartości... ale jeśli umieścisz to miejsce przed % będzie ok wszystko i nie pominąć nic.

 1
Author: Cristian Babarusi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-19 13:52:06
#include <stdio.h>
// read a line into str, return length
int read_line(char str[]) {
int c, i=0;
c = getchar();
while (c != '\n' && c != EOF) { 
   str[i] = c;
   c = getchar();
   i++;
}
str[i] = '\0';
return i;
}
 1
Author: ayush bhorse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-21 19:45:13
#include<stdio.h>
int main()
{
   char name[100];
   printf("Enter your name: ");
   scanf("%[^\n]s",name);
   printf("Your Name is: %s",name);
   return 0;
}
 0
Author: Pranta Palit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-26 06:29:16

Za pomocą tego kodu można wejść aż do naciśnięcia klawisza enter.

char ch[100];
int i;
for (i = 0; ch[i] != '\n'; i++)
{
    scanf("%c ", &ch[i]);
}
 0
Author: iFTEKHAR LIVE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-23 12:30:36

Podczas gdy wyżej wymienione metody działają, ale każda z nich ma swój własny rodzaj problemów.

Możesz użyć getline() lub getdelim(), Jeśli używasz platformy obsługiwanej przez posix. Jeśli używasz windows i minigw jako kompilatora, to powinien być dostępny.

getline() jest zdefiniowana jako:

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

Aby pobierać dane wejściowe, najpierw musisz utworzyć wskaźnik do typu char.

#include <stdio.h>
#include<stdlib.h>

// s is a pointer to char type.
char *s;
// size is of size_t type, this number varies based on your guess of 
// how long the input is, even if the number is small, it isn't going 
// to be a problem
size_t size = 10;

int main(){
// allocate s with the necessary memory needed, +1 is added 
// as its input also contains, /n character at the end.
    s = (char *)malloc(size+1);
    getline(&s,&size,stdin);
    printf("%s",s);
    return 0;
}

Przykładowe Wejście: Hello world to the world!

Wyjście: Hello world to the world!\n

Jedna rzecz do zauważ tutaj, że mimo iż przydzielona pamięć dla s wynosi 11 bajtów, gdzie jako rozmiar wejściowy wynosi 26 bajtów, getline realokuje s używając realloc().

Więc nie ma znaczenia, jak długi jest Twój wkład.

size jest aktualizowany z numeremodczytanych bajtów, zgodnie z powyższym przykładowym wejściem {[9] } będzie 27.

getline() uważa również \n za input.So Twoje " s "będzie trzymać" \n " na końcu.

Istnieje również bardziej ogólna wersja getline(), czyli getdelim(), która wymaga jeszcze jednego dodatkowego argumentu, to jest delimiter.

getdelim() jest zdefiniowana jako:

ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);

Linux man page

 0
Author: nilsocket,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-19 12:36:25

Jeśli chcesz przeczytać więcej niż jedną linię, musisz wyczyścić bufor. Przykład:

int n;
scanf("%d", &n);
char str[1001];
char temp;
scanf("%c",&temp); // temp statement to clear buffer
scanf("%[^\n]",str);
 0
Author: levan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-31 09:43:37

"%s" będzie odczytywał dane wejściowe do czasu osiągnięcia spacji.

Gets może być dobrym miejscem do rozpoczęcia, Jeśli chcesz odczytać linię (tzn. wszystkie znaki łącznie z białymi spacjami, aż do osiągnięcia znaku nowej linii).

 -1
Author: davin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-08 16:40:20

"Barack Obama" ma przestrzeń między 'Barack' a 'Obama'. W tym celu należy użyć tego kodu;

#include <stdio.h>
int main()
{
    printf("Enter your name\n");
   char a[80];
   gets(a);
   printf("Your name is %s\n", a);
   return 0;
}
 -1
Author: Koech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-28 22:30:15
scanf("%s",name);

Użyj & z scanf input

 -4
Author: Vi_Hari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-15 17:41:15