Есть несколько способов приблизиться к разбиению вашей входной строки после 2-го символа, если ввод содержит 'b'
или после 1-го символа в противном случае. Поскольку вы имеете дело с 1
или 2
, все, что вам нужно сделать, это определить, присутствует ли 'b'
. Самый простой способ сделать это с помощью strchr()
, который будет искать в данной строке первое вхождение символа, возвращая указатель на этот символ, если он найден, или NULL
в противном случае. См. man 3 strchr
Таким образом, вы можете использовать strchr
, чтобы проверить, присутствует ли 'b'
, если возвращаемое значение не равно NULL
, разделить строку после 2-го символа, если это NULL
, разделить его после первого.
Простая реализация с использованием троичной переменной для установки размера разделения после ввода для чтения в буфер buf
будет выглядеть так:
char part2[MAXC]; /* buffer to hold 2nd part */
size_t split; /* number of chars to split */
/* if buf contains 'b', set split at 2, otherwise set at 1 */
split = strchr(buf, 'b') ? 2 : 1;
strcpy (part2, buf + split); /* copy part2 from buf */
buf[split] = 0; /* nul-terminate buf at split */
Быстрая реализация, позволяющая вам ввести столько строк, сколько вам нужно, и она будет разбита после 1-го или 2-го символа в зависимости от отсутствия или наличия 'b'
будет:
#include <stdio.h>
#include <string.h>
#define MAXC 1024 /* if you need a constant, #define one (or more) */
int main (void) {
char buf[MAXC]; /* buffer to hold line of input */
fputs ("Enter a string to split (or [Enter] alone to exit)\n\n"
"string: ", stdout);
while (fgets (buf, MAXC, stdin)) { /* loop reading each line */
char part2[MAXC]; /* buffer to hold 2nd part */
size_t split; /* number of chars to split */
if (*buf == '\n') /* if [Enter] alone, exit */
break;
/* if buf contains 'b', set split at 2, otherwise set at 1 */
split = strchr(buf, 'b') ? 2 : 1;
strcpy (part2, buf + split); /* copy part2 from buf */
buf[split] = 0; /* nul-terminate buf at split */
printf (" part1: %s\n part2: %s\nstring: ", buf, part2);
}
}
( примечание: если вы не знакомы с оператором троичного , это просто (test) ? if_true : if_false
. Выше это просто сокращение для if (strchar (buf, 'b') != NULL) split = 2; else split = 1;
)
Пример использования / Вывод
$ ./bin/splitb
Enter a string to split (or [Enter] alone to exit)
string: look out
part1: l
part2: ook out
string: look out below
part1: lo
part2: ok out below
string:
Дайте мне знать, если это то, что вы хотели. Если нет, я с удовольствием помогу дальше. Кроме того, если у вас есть какие-либо вопросы, просто дайте мне знать.
Редактировать на основе комментариев
До сих пор неясно, какой у вас список заметок в вашем заголовочный файл, но вы можете просто использовать строковую константу для хранения букв заметок, например,
#define NOTES "abcdefg" /* (that can be a string constant as well) */
(вы можете добавить верхний регистр, если необходимо, или вы можете преобразовать ввод в нижний - все, что работает для вы)
Если вам просто нужно найти первое вхождение одной из букв в строке NOTES
, то strpbrk()
позволит вам просто вернуть указатель на первый символ NOTES
найдено в вашем string
. (у вас должен быть какой-то способ обработки ввода пользователя, например, "the note cflat"
, который будет делиться на первое 'e'
вместо 'c'
, но вам нужно будет предоставить дополнительные подробности там)
Другое соображение как долго может быть note
. Если это всегда 1 символ, то вы можете упростить это, просто сравнив первый символ в строке, используя strchr (NOTES, buf[0])
(что меняет привычный подход к использованию strchr()
вокруг - с использованием первой строки NOTES
и первый символ, прочитанный из пользовательского ввода.
При общем подходе, который разбил бы "---cflat---"
на "---c"
и "flat---"
, ваша функция может быть похожа на:
int split_note_and_chord (char *string, char *note, char *chord)
{
char *p = strpbrk (string, NOTES); /* pointer to first of NOTES in string */
if (p != NULL) { /* if found */
strcpy (note, string); /* copy string to note */
note[p - string + 1] = 0; /* nul-terminate after note */
strcpy (chord, p + 1); /* copy rest to chord */
return 1; /* return success */
}
*note = 0; /* make note and chord empty-string */
*chord = 0;
return 0; /* return failure */
}
( note: если в NOTES
не найден символ, то note
и chord
превращаются в пустую строку с помощью nul-terminating в первом символе до возврата нуля к индикации не найдена заметка.)
Быстрая реализация, подобная первой, могла бы быть такой:
#include <stdio.h>
#include <string.h>
#define MAXC 1024 /* if you need a constant, #define one (or more) */
#define NOTES "abcdefg" /* (that can be a string constant as well) */
int split_note_and_chord (char *string, char *note, char *chord)
{
...
}
int main (void) {
char buf[MAXC], /* buffer to hold line of input */
note[MAXC], /* buffer for node */
chord[MAXC]; /* buffer for chord */
fputs ("Enter a string with node and chord (or [Enter] alone to exit)\n\n"
"string: ", stdout);
/* loop reading each line until [Enter] alone */
while (fgets (buf, MAXC, stdin) && *buf != '\n') {
if (split_note_and_chord (buf, note, chord))
printf (" note : %s\n chord : %s\n", note, chord);
else
fputs ("\nerror: note not found in string.\n\n", stderr);
fputs ("string: ", stdout);
}
return 0;
}
( note: , которая при использовании fgets()
будет читать и включите '\n'
, полученный в результате нажатия пользователем Введите в buf
, и, таким образом, он также будет включен в остаток, скопированный в chord
. Вы можете использовать buf[strcspn (buf, "\n")] = 0;
, чтобы обрезать его с buf
- или из chord
путем замены chord
на buf
в вызовите с использованием strcspn()
в качестве индекса для nul-terminate в.)
( также обратите внимание: вы можете настроить MAXC
в соответствии со своими потребностями - вот почему вы объявляете константу во-первых, чтобы сделать простым изменением одной строки в верхней части файла)
Пример использования / Вывод
Использование вашей функции для разделения различных входные данные приведут к следующему:
$ ./bin/splitb3
Enter a string with node and chord (or [Enter] alone to exit)
string: ---cflat---
note : ---c
chord : flat---
string: asharp
note : a
chord : sharp
string: bflat
note : b
chord : flat
string: hook
error: note not found in string.
string: c
note : c
chord :
Существует множество способов сделать это, и наилучший подход к нему будет зависеть от того, как у вас есть ноты и аккорды, определенные в заголовке, а также а какие, если таковые имеются, ограничения, которые вы накладываете на формат, который требуется от пользователя вводить Если вам нужна дополнительная помощь, отредактируйте ваш вопрос и Добавьте содержимое вашего заголовка, чтобы мы знали, как они были объявлены и определены, а также перечислили любые ограничения, которые вы хотите наложить на то, что пользователь может ввести .