【问题标题】:Split user inputted string to char array将用户输入的字符串拆分为 char 数组
【发布时间】:2024-01-04 11:51:01
【问题描述】:

我正在与 c 进行约会日历程序。我的程序使用用户输入的命令添加了一个新约会:“A'description''mm''dd''hh'” 其中 description 是一个最多 20 个字符的字符串,mm 是月,dd 是天,hh 是小时。月、日和小时可以是 1 或 2 个字符长。 我试图实现 readInput 函数,它通过空格键拆分输入字符串并返回一个字符数组,其中包含:[description, mm, dd, hh] 所以我可以很容易地得到:

desc = array[1];
month = array[2];
day = array[3];
hour = array[4];

实现这个功能比我想象的要难,而且我失败得很惨。我不想要指针,只想要一个包含字符串的基本 char 数组。我应该如何实现这个?下面是我的主要功能。

int main()
{   
    struct Calendar c;
    c.numOfAppointments = 0;
    while (true) {
        char str[30];
        printf("Command: ");
        scanf("%[^\n]%*c", str);
        if (str[0] == 'A')
        {
            char command = readInput(str); /*implement this */
        }
        else if (str[0] == 'L')
        {
            printCalendar(c);
        }
        else if (str[0] == 'Q')
        {
            printf("Exiting program...");
            break;
        }
    }
}

假设我输入:牙医 4 20 10

返回的数组应该是:["dentist","4","20","10"]

【问题讨论】:

  • 感谢您添加示例数据。您说您希望结果为“char 数组”(char *),但您的示例输出是字符串数组(char **)。为什么不希望将结果作为结构体呢?
  • 牙医前的“A”是什么?

标签: arrays c char


【解决方案1】:

实现这个功能比我想象的要难,而且我失败得很惨。

不要对自己太苛刻……你正在学习。我们学习编程主要是通过我们的错误:-)

我不想要指针,只是一个包含字符串的基本 char 数组。

啊,那么,你的问题是:它是一个字符数组,还是一个字符串数组?

C 中的字符串是指向内存中以\0 结尾的字符序列的指针。

“字符串数组”是指针数组!

你可以做的是:

  1. 将您的行读入适当的字符数组。
  2. 在此数组的适当位置放置“\0”,以指示行尾组件。
  3. 有第二个数组,例如const char * array_of_fields[4],其元素为字符串。

  1. 有一个struct { const char* description, month, day, hour; }

然后

  1. 将第二个数组的元素或结构的元素设置为指向字符数组中的适当位置。

【讨论】:

    【解决方案2】:

    使用fgets(str, strlen(str), stdin) 读取您的字符串。下一步是解析字符串。由于您的输入包含一个变量描述,然后是一个有点可变的日期时间格式。解析的方法是从末尾开始找到描述和月份之间的分隔符sep,这将是倒数第三个空格(n = 2)。您现在知道sep 之前的内容是“A”前缀和描述,之后的所有内容都是日期时间。可以使用strptime(3) 解析日期时间:

    #define _POSIX_C_SOURCE 200809L
    #define _XOPEN_SOURCE
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    int rindexn(const char *s, char c, size_t n) {
        int i = strlen(s);
        if(!i) return -1;
        for(i--; i >= 0; i--) {
            if(s[i] == c) {
                if(!n) break;
                n--;
            }
        }
        return i >= 0 ? i : -1;
    }
    
    int main() {
        const char *str = "A dentist 4 20 10";
    
        // parse
        if(!strncmp(str, "A ", 2)) {
            printf("A space prefix missing");
            return 1;
        }
        int sep = rindexn(str, ' ', 2);
        if(sep == -1) {
            printf("sep not found\n");
            return 1;
        }
        struct tm tm;
        char *end = strptime(str + sep + 1, "%m %d %H", &tm);
        if(!end) {
            pritnf("cannot parse date time\n");
            return 1;
        } else if(*end) {
            printf("extra data after hour\n");
            return 1;
        }
    
        // convert to whatever format you decide
        printf("description = \"%.*s\", month = %d, day = %d, hour = %d",
            (int) sep - 2, str + 2, tm.tm_mon, tm.tm_mday, tm.tm_hour);
    }
    

    给出以下输出:

    description = "dentist", month = 3, day = 20, hour = 10
    

    【讨论】: