Как вы разрешаете вводить пробелы с помощью scanf? [дубликат]
этот вопрос уже есть ответ здесь:
читает строку из ввода с пробелом?
14 ответов
использовать следующий код:
char *name = malloc(sizeof(char) + 256);
printf("What is your name? ");
scanf("%s", name);
printf("Hello %s. Nice to meet you.n", name);
пользователь может ввести свое имя, но когда они введите имя с пробелом, как Lucas Aardvark,scanf() просто отрезает все после Lucas. Как сделать scanf() разрешить пробелы
11 ответов:
люди (и особенно новичков) никогда не должны использовать
scanf("%s")илиgets()или любые другие функции, которые не имеют защиты от переполнения буфера, если вы не знаете наверняка, что вход всегда будет иметь определенный формат (и, возможно, даже тогда).помните, чем
scanfрасшифровывается как "сканирование отформатировано" и там очень мало меньше отформатирован, чем введенные пользователем данные. Это идеально, если у вас есть полный контроль над форматом входных данных, но как правило, не подходит для пользовательского ввода.использовать
fgets()(где и защиту от переполнения буфера), чтобы получить вход в строкуsscanf()оценить его. Так как вы просто хотите, что пользователь ввел без разбора, вам действительно не нужноsscanf()в этом случае в любом случае:#include <stdio.h> #include <stdlib.h> #include <string.h> /* Maximum name size + 1. */ #define MAX_NAME_SZ 256 int main(int argC, char *argV[]) { /* Allocate memory and check if okay. */ char *name = malloc(MAX_NAME_SZ); if (name == NULL) { printf("No memory\n"); return 1; } /* Ask user for name. */ printf("What is your name? "); /* Get the name, with size limit. */ fgets(name, MAX_NAME_SZ, stdin); /* Remove trailing newline, if there. */ if ((strlen(name) > 0) && (name[strlen (name) - 1] == '\n')) name[strlen (name) - 1] = ''; /* Say hello. */ printf("Hello %s. Nice to meet you.\n", name); /* Free memory and exit. */ free (name); return 0; }
в этом примере используется инвертированный набор, так что scanf не принимает значений, пока не встретится '\п'-- перевод строки, пробелы сохраняются также
#include <stdio.h> int main (int argc, char const *argv[]) { char name[20]; scanf("%[^\n]s",name); printf("%s\n", name); return 0; }
Вы можете использовать этот
char name[20]; scanf("%20[^\n]", name);или это
void getText(char *message, char *variable, int size){ printf("\n %s: ", message); fgets(variable, sizeof(char) * size, stdin); sscanf(variable, "%[^\n]", variable); } char name[20]; getText("Your name", name, 20);
не используйте
scanf()читать строки без указания ширины поля. Вы также должны проверить возвращаемые значения на наличие ошибок:#include <stdio.h> #define NAME_MAX 80 #define NAME_MAX_S "80" int main(void) { static char name[NAME_MAX + 1]; // + 1 because of null if(scanf("%" NAME_MAX_S "[^\n]", name) != 1) { fputs("io error or premature end of line\n", stderr); return 1; } printf("Hello %s. Nice to meet you.\n", name); }в качестве альтернативы, используйте
fgets():#include <stdio.h> #define NAME_MAX 80 int main(void) { static char name[NAME_MAX + 2]; // + 2 because of newline and null if(!fgets(name, sizeof(name), stdin)) { fputs("io error\n", stderr); return 1; } // don't print newline printf("Hello %.*s. Nice to meet you.\n", strlen(name) - 1, name); }
можно использовать
fgets()функция для чтения строки или использованияscanf("%[^\n]s",name);таким образом, чтение строки завершится при обнаружении символа новой строки.
теперь часть POSIX, тем не менее.
Он также заботится о проблеме выделения буфера, о которой вы спрашивали ранее, хотя вам нужно позаботиться о
freeing памяти.
Если кто - то все еще ищет, вот что сработало для меня - прочитать произвольную длину строки, включая пробелы.
благодаря многим плакатам в интернете для обмена этим простым и элегантным решением. Если это работает, кредит идет к ним, но любые ошибки мои.
char *name; scanf ("%m[^\n]s",&name); printf ("%s\n",name);
вы можете использовать
scanfдля этой цели с небольшую хитрость. На самом деле, вы должны разрешить ввод данных пользователем, пока пользователь не нажмет Enter (\n). Это будет учитывать каждый символ, в том числе пробел. Вот пример:int main() { char string[100], c; int i; printf("Enter the string: "); scanf("%s", string); i = strlen(string); // length of user input till first space do { scanf("%c", &c); string[i++] = c; // reading characters after first space (including it) } while (c != '\n'); // until user hits Enter string[i - 1] = 0; // string terminating return 0; }как это работает? Когда пользователь вводит символы из стандартного ввода, они будут храниться в строка переменной до первого пробела. После этого остальная часть записи останется во входном потоке и будет ждать следующего scanf. Далее, у нас есть
forцикл, который принимает символ за символом из входного потока (до\n) и присоединяет их к концу строка переменная, таким образом, образуя полную строку так же, как пользовательский ввод с клавиатуры.надеюсь, что это поможет кому-то!
в то время как вы действительно не должны использовать
scanf()для такого рода вещей, потому что есть гораздо лучшие вызовы, такие какgets()илиgetline(), Это можно сделать:#include <stdio.h> char* scan_line(char* buffer, int buffer_size); char* scan_line(char* buffer, int buffer_size) { char* p = buffer; int count = 0; do { char c; scanf("%c", &c); // scan a single character // break on end of line, string terminating NUL, or end of file if (c == '\r' || c == '\n' || c == 0 || c == EOF) { *p = 0; break; } *p++ = c; // add the valid character into the buffer } while (count < buffer_size - 1); // don't overrun the buffer // ensure the string is null terminated buffer[buffer_size - 1] = 0; return buffer; } #define MAX_SCAN_LENGTH 1024 int main() { char s[MAX_SCAN_LENGTH]; printf("Enter a string: "); scan_line(s, MAX_SCAN_LENGTH); printf("got: \"%s\"\n\n", s); return 0; }
Comments