Как читать пробел с помощью scanf в c?
проблема: мне нужно иметь возможность определить, когда два пробела происходят последовательно.
Я прочитал следующие вопросы:
как читать строку из файла с разделителями n
как читать scanf с пробелами
и я знаю о проблемах scanf:http://c-faq.com/stdio/scanfprobs.html
вход будет в следующем формате:
1 5 3 2 4 6 2 1 9 0
два пробела указывает, что следующий набор данных должен обрабатываться и сравниваться с самим собой. Длина строки неизвестна, а число или целые числа в каждой группе неизвестны. Два пробела-это самое большее, что отделит следующий набор данных.
хотя я могу использовать fgets и различные встроенные функции для решения этой проблемы, я нахожусь в точке, где решение проблемы с scanf на данный момент, вероятно, будет проще. Однако, если это не так, использование fgets, strtok и atoi сделает большую часть работа, но мне все еще нужно определить два пробела подряд.
внизу будет принимать числа до нецелым занесены.
while ( scanf ( "%d", &x ) == 1 )
то, что мне нужно, это читать пробелы, а также, если есть два последовательных пробела, я буду программа, чтобы сделать что-то другое со следующим набором данных.
и как только я получаю пробел, я не знаю, как сказать:
if ((input == "whitespace") && (previousInput == "whitespace")) ya da ya da else (input == "whitespace") ya da ya da else ya da ya da
Я ценю ваше время и благодарю вас за вашу помощь.
урок: В то время как решение для scanf опубликовано ниже Джонатаном Леффлером, решение было немного более простым с getc (путем требования менее глубокого знания внутреннего scanf, регулярных выражений и char). Оглядываясь назад, лучшее знание регулярных выражений, scanf и char облегчили бы проблему и, конечно, знали, какие функции доступны, и какой из них был бы лучшим для использования с самого начала.
5 ответов
getc
и ungetc
являются друзьями
#include <stdio.h>
int main(void) {
int ch, spaces, x;
while (1) {
spaces = 0;
while (((ch = getc(stdin)) != EOF) && (ch == ' ')) spaces++;
if (ch == EOF) break;
ungetc(ch, stdin);
if (scanf("%d", &x) != 1) break;
printf("%d was preceded by %d spaces\n", x, spaces);
}
return 0;
}
демо на http://ideone.com/xipm1
редактировать Rahhhhhhhhh ... Я загрузил это как C++. Вот то же самое, но теперь C99 strict
( http://ideone.com/mGeVk )
while ( scanf ( "%c", &x ) == 1 )
используя %c
вы можете читать пробелы, вы должны только читать все данные и хранить в массиве. Тогда выделите char* cptr
и получить set cptr
для начала массива, затем вы анализируете свой массив, и если вы хотите прочитать десятичные числа, вы можете использовать просто sscanf
on cptr
пока вы хотите прочитать decimal, но у вас должен быть указатель в хорошем положении на массиве (на номер, который вы хотите прочитать)
if (((*(cptr + 1)) == ' ') && ((*cptr)== ' '))
ya da ya da
else ((*cptr)== ' '))
ya da ya da
sscanf(++cptr, "%d", &x);
else
ya da ya da
если вы действительно хотите scanf
введите функциональность, вы можете использовать fgets
и sscanf
, и использовать %n
спецификатор, чтобы получить scanf, чтобы дать вашей программе смещения для начала и конца каждого пробела в то же время он выполняет остальную часть своей работы.
в противном случае, бросьте все scanf
семья. На мой взгляд, это, возможно, самая бесполезная часть стандартной библиотеки.
каково ваше определение "белого пространства"?
честно говоря, я не думаю, что хотел бы попробовать использовать scanf()
определить двойные пробелы; почти каждый другой метод был бы намного проще.
однако, если вы настаиваете на выполнении не отчаянно разумного, то вы можете использовать код, полученный из следующего:
#include <stdio.h>
#include <string.h>
int main(void)
{
int d;
char sp[3] = "";
int n;
while ((n = scanf("%d%2[ \t]", &d, sp)) > 0)
{
printf("n = %d; d = %d; sp = <<%s>>", n, d, sp);
if (n == 2 && strlen(sp) == 2)
printf(" end of group");
putchar('\n');
}
return 0;
}
квадратные скобки заключают класс символов, а 2 перед ним настаивают не более чем на 2 символах из класса. Вы могли бы беспокоиться об этом, читая новую строку и пытаясь получить больше данных, чтобы удовлетворить класс символов, который может быть разрешен путем удаления новой строки из класса символов. Но тогда это зависит от вашего определения пробела и от того, заканчиваются ли группы автоматически новой строкой или нет. Не помешало бы сбросить sp[0] = '';
в конце цикла.
вы могли бы, возможно, лучше перевернуть поля, чтобы обнаружить два пробела перед числом. Но что бы не в обычный случай, так что вы бы вернуться на простой "%d"
формат для чтения номера (и если это не удается, вы знаете, что у вас нет ни пробелов, ни ошибки номера). Обратите внимание, что %d
жует ведущее белое пространство (как определено стандартом) - все из них.
чем больше я смотрю на это, тем меньше мне нравится 'scanf()
только. Напомни мне не ходить на занятия в твой университет, пожалуйста.
вот решение, которое использует только функцию scanf (). Я использовал sscanf () в этом примере примерно для той же функциональности.
#include <stdio.h>
int p_1_cnt = 0, p_2_cnt = 0;
void process_1(int x)
{
p_1_cnt++;
}
void process_2(int x)
{
p_2_cnt++;
}
char * input_line = "1 5 3 2 4 6 2 1 9 0";
int main(void)
{
char * ip = input_line;
int x = 0, ws_0 = 0, ws_1 = 0, preceding_spaces = 1, fields = -2;
while (sscanf (ip, "%d%n %n", &x, &ws_0, &ws_1) > 0)
{
ip += ws_0;
if ((preceding_spaces) == 1)
process_1(x);
else
process_2(x);
preceding_spaces = ws_1 - ws_0;
}
printf("\np_1_cnt = %d, p_2_cnt = %d", p_1_cnt, p_2_cnt);
_fgetchar();
return 0;
}