разбить введенную пользователем строку на указанную c букву в c - PullRequest
1 голос
/ 03 апреля 2020

Я пытаюсь написать оператор if else, который просматривает пользовательский ввод и затем разделяет его после индекса [1], если строка содержит букву b, или разделяет после индекса [0], если ввод строки не включает в себя букву b , Как бы я подошел к этому? Довольно плохо знаком с C, поэтому не слишком уверен.

Это то, что я имею до сих пор ... Я думаю, что я на правильном пути и пытаюсь выяснить, как бы я закончил sh так он делает то, что я хочу.

int split_note_and_chord(char* string, char* note, char* chord)
{
  for(user input doesnt have b in it)
  {
    if(i = 0; i <index; i++)
    {
      note[i] = string[i];
    }
    note[index] = 0;
    else{ if(i = 0; i < index; i++)
    {
      note[i] = strlen(string[2]);
    }
  }
}

Ответы [ 2 ]

0 голосов
/ 03 апреля 2020

Есть несколько способов приблизиться к разбиению вашей входной строки после 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 :

Существует множество способов сделать это, и наилучший подход к нему будет зависеть от того, как у вас есть ноты и аккорды, определенные в заголовке, а также а какие, если таковые имеются, ограничения, которые вы накладываете на формат, который требуется от пользователя вводить Если вам нужна дополнительная помощь, отредактируйте ваш вопрос и Добавьте содержимое вашего заголовка, чтобы мы знали, как они были объявлены и определены, а также перечислили любые ограничения, которые вы хотите наложить на то, что пользователь может ввести .

0 голосов
/ 03 апреля 2020

C строка - это не что иное, как массив символов

string.h предоставляет удобные функции для проверки содержимого строки

, которые можно использовать, если условие и функции strstr и strchr для вашей логики c

Например

#include <stdio.h>
#include <string.h>


int main () {
   const char *input = "backwards";
   char *ret;

   ret = strstr(input, "b");

   if( ret != NULL ) {

   } else {

   }
}

strstr вернет NULL, если b не существует

Вы также можете использовать strchr если вы хотите, чтобы второй аргумент представлял собой один символ strchr(input, 'b');

...