【问题标题】:split a user inputed string at a specific letter in c在 c 中的特定字母处拆分用户输入的字符串
【发布时间】:2020-04-03 04:50:39
【问题描述】:

我正在尝试编写一个 if else 语句,该语句查看用户输入,如果字符串包含字母 b,则在 index[1] 之后将其拆分,如果字符串输入不包含字母 b,则在 index[0] 之后拆分.我将如何处理?对 C 很陌生,所以不太确定。

这就是我到目前为止所拥有的......我认为我走在正确的道路上,并且正在努力弄清楚我将如何完成它,以便它完成我想要它做的事情。

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]);
    }
  }
}

【问题讨论】:

  • int split_note_and_chord(char* string, char* note, char* chord) { for(用户输入没有b){ if(i = 0; i
  • 这是我到目前为止所拥有的......我认为我走在正确的道路上,并且正在努力弄清楚我将如何完成它,以便它完成我想要它做的事情。

标签: c split


【解决方案1】:

C 字符串只不过是一个字符数组

string.h 提供方便的函数来检查字符串内容

您可以将 if 条件和 strstrstrchr 函数用于您的逻辑

例如

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


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

   ret = strstr(input, "b");

   if( ret != NULL ) {

   } else {

   }
}

如果b 不存在,strstr 将返回 NULL

如果您希望第二个参数为单个字符strchr(input, 'b');,您也可以使用strchr

【解决方案2】:

如果输入包含'b',则有多种方法可以在第二个字符之后拆分输入字符串,否则在第一个字符之后拆分。由于您正在处理12,因此您需要做的就是确定'b' 是否存在。最简单的方法是使用strchr(),它将在给定的字符串中搜索第一次出现的字符,如果找到则返回指向该字符的指针,否则返回NULL。见man 3 strchr

所以您可以使用strchr 来测试'b' 是否存在,如果返回不是NULL,则在第二个字符之后拆分字符串,如果是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 */

一种快速实现,允许您输入任意数量的字符串,它会在第一个或第二个字符之后拆分,具体取决于缺席或'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 的第一个字符的指针在您的@ 中找到987654343@。 (您必须有某种方式来处理用户输入,例如"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 */
}

(注意:如果在NOTES 中没有找到字符,那么notechord 会被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;
}

(注意: 使用fgets() 将读取并包含用户按Enter 生成的'\n' buf,因此它也将被包含在内在复制到chord 的其余部分中。您可以使用buf[strcspn (buf, "\n")] = 0;buf 修剪它 - 或通过在使用strcspn() 作为nul 索引的调用中将chord 替换为buf 来从chord 修剪它- 终止于。)

(另请注意:您可以调整 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 :

有很多不同的方法可以做到这一点,以及如何最好地处理它取决于您如何在标题中定义音符和和弦 - 以及您对格式设置的限制(如果有的话)要求用户输入。如果您需要更多帮助,请编辑您的问题并添加标题的内容,以便我们知道它们是如何声明和定义的,并列出您希望对用户可以施加的任何约束输入。

【讨论】:

  • 嘿,大卫,感谢您的帮助,我越是查看我的问题,我认为我的处理方式是错误的,所以我的问题是我希望用户输入一个包含注释的字符串终端中的名称和和弦名称作为单个字符串,但是我想将音符和和弦作为两个单独的字符串返回。我已经在 .h 文件夹中定义了所有的音符和和弦,这就是为什么我使用 int split(char* string, char* note, char* chord) 在单个字符串中找到音符名称和在那里拆分,但我该怎么做才能让我的拆分函数知道在哪里拆分字符串
  • 分割函数的工作方式完全相同。关键是您必须在 notechord 中提供足够的存储空间,以便您从 string 拆分的任何内容都适合每个。当您传递string 时,您可以使用strbprk 查找给定accept 字符串中的第一个字符(请参阅man 3 strpbrk),然后在指向y 的字符处复制和拆分string 返回的strpbrk。如果您仍想在str[0]str[1] 之后进行拆分,它将完全如上所示。如果卡住了,请删除另一条评论。
猜你喜欢
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-20
相关资源
最近更新 更多