чтение строки с пробелами с помощью sscanf
для проекта, я пытаюсь прочитать int и строку из строки. Единственная проблема заключается в том, что sscanf прерывает чтение %s, когда видит пробел. Есть ли вообще обойти это ограничение? Вот пример того, что я пытаюсь сделать:
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char** argv) {
int age;
char* buffer;
buffer = malloc(200 * sizeof(char));
sscanf("19 cool kid", "%d %s", &age, buffer);
printf("%s is %d years oldn", buffer, age);
return 0;
}
что он печатает: "круто 19 лет", где мне нужно "прохладный ребенок 19 лет". Кто-нибудь знает как это исправить?
5 ответов
следующая строка начнет читать номер (%d
), а затем все, что отличается от вкладок или новых строк (%[^\t\n]
).
sscanf("19 cool kid", "%d %[^\t\n]", &age, buffer);
вы хотите %c
спецификатор преобразования, который просто считывает последовательность символов без особой обработки пробелов.
обратите внимание, что сначала вам нужно заполнить буфер нулями, потому что %c
спецификатор не записывает нуль-Терминатор. Вам также необходимо указать количество символов для чтения (в противном случае по умолчанию используется только 1):
memset(buffer, 0, 200);
sscanf("19 cool kid", "%d %199c", &age, buffer);
если вы хотите сканировать до конца строки (зачистка новой строки, если есть), просто используйте:
char *x = "19 cool kid";
sscanf (x, "%d %[^\n]", &age, buffer);
потому что %s
соответствует только символам без пробелов и останавливается на первом найденном пробеле. The %[^\n]
спецификатор формата будет соответствовать каждому символу, который не (из-за ^
) на выбор дали (это строки). Другими словами, он будет соответствовать любому другому персонажу.
имейте в виду, что вы должны выделяться достаточно места в буфере, чтобы взять строку, так как вы не можете быть уверены, сколько будет прочитано (хорошая причина держаться подальше от scanf/fscanf
если вы не используете определенную ширину поля).
вы могли бы сделать это:
char *x = "19 cool kid";
char *buffer = malloc (strlen (x) + 1);
sscanf (x, "%d %[^\n]", &age, buffer);
(вам не нужно * sizeof(char)
так вот всегда 1 по определению).
Так как вы хотите, чтобы конечная строка из ввода, вы можете использовать %n
(количество символов, использованных до сих пор), чтобы получить позицию, с которой начинается конечная строка. Это позволяет избежать проблем с копиями памяти и размером буфера, но стоит того, что вам может потребоваться сделать их явно, если вы хотите копию.
const char *input = "19 cool kid";
int age;
int nameStart = 0;
sscanf(input, "%d %n", &age, &nameStart);
printf("%s is %d years old\n", input + nameStart, age);
выходы:
cool kid is 19 years old
Я думаю, это то, что вы хотите, он делает именно то, что вы указали.
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char** argv) {
int age;
char* buffer;
buffer = malloc(200 * sizeof(char));
sscanf("19 cool kid", "%d cool %s", &age, buffer);
printf("cool %s is %d years old\n", buffer, age);
return 0;
}
формат ожидает: сначала число (и помещает его туда, куда указывает &age), затем пробелы (ноль или больше), затем литеральная строка "круто", затем пробелы (ноль или больше) снова, а затем, наконец, строка (и поместите это в любые буферные точки). Вы забыли "классную" часть в строке формата, поэтому формат тогда просто предполагает, что это строка, которую вы хотели назначить буферу. Но вы не хочу назначать эту строку, просто пропустите ее.
альтернатива, у вас также может быть строка формата, например: "%d %s %s", но затем вы должны назначить для нее другой буфер (с другим именем) и распечатать его как: "%s %s-это %d years old\n".