在 C 中将单词从camelCase转换为snake_case

标签 c computer-science

我想要编码的是,如果我输入camelcase,它应该只打印出camelcase,但是如果其中包含任何大写字母,例如,如果我输入camelCase,它应该打印出camel_case

下面是我正在处理的问题,但问题是,如果我输入 camelCase,它会打印出 camel_ase

有人可以告诉我原因以及如何解决吗?

#include <stdio.h>
#include <ctype.h>

int main() {
    char ch;
    char input[100];
    int i = 0;

    while ((ch = getchar()) != EOF) {
        input[i] = ch;
        if (isupper(input[i])) {
            input[i] = '_';
            //input[i+1] = tolower(ch);
        } else {
            input[i] = ch;
        }
        printf("%c", input[i]);

        i++;
    }
}

最佳答案

首先查看您的代码并考虑当有人输入超过 100 个字符的单词时会发生什么 -> 未定义的行为。如果您使用缓冲区进行输入,则总是必须添加检查,以免溢出此缓冲区。

但是,当你直接打印字符时,为什么还需要缓冲区呢?您所展示的方法完全没有必要。试试这个:

#include <stdio.h>
#include <ctype.h>

int main()
{
    int ch;
    int firstChar = 1; // needed to also accept PascalCase
    while((ch = getchar())!= EOF)
    {
        if(isupper(ch))
        {
            if (!firstChar) putchar('_');
            putchar(tolower(ch));

        } else
        {
            putchar(ch);
        }
        firstChar = 0;
    }
}
<小时/>

旁注:我更改了 ch 的类型至int 。这是因为getchar()返回 int , putchar() , isupper()islower()采取int它们都使用 unsigned char 的值,或EOF 。如char允许在签名为char的平台上进行签名,你会得到未定义的行为,用负值 char 调用这些函数。 。我知道,这有点复杂。解决此问题的另一种方法是始终转换您的 charunsigned char当调用一个采用 unsigned char 值的函数时作为int .

<小时/>

当您使用缓冲区时,它现在没用,您可能会对充分利用缓冲区的可能解决方案感兴趣:一次读取和写入一整行。这比为每个字符调用一个函数稍微高效一些。这是一个执行此操作的示例:

#include <stdio.h>

static size_t toSnakeCase(char *out, size_t outSize, const char *in)
{
    const char *inp = in;
    size_t n = 0;
    while (n < outSize - 1 && *inp)
    {
        if (*inp >= 'A' && *inp <= 'Z')
        {
            if (n > outSize - 3)
            {
                out[n++] = 0;
                return n;
            }
            out[n++] = '_';
            out[n++] = *inp + ('a' - 'A');
        }
        else
        {
            out[n++] = *inp;
        }
        ++inp;
    }
    out[n++] = 0;
    return n;
}

int main(void)
{
    char inbuf[512];
    char outbuf[1024]; // twice the lenght of the input is upper bound

    while (fgets(inbuf, 512, stdin))
    {
        toSnakeCase(outbuf, 1024, inbuf);
        fputs(outbuf, stdout);
    }
    return 0;
}

此版本还避免 isupper()tolower() ,但牺牲了便携性。 当字符编码按顺序包含字母并且大写字母在小写字母之前时才有效。对于 ASCII,这些假设成立。请注意,什么被视为(大写)字母也可能取决于区域设置。上面的程序仅适用于英语中的字母 A-Z。

关于在 C 中将单词从camelCase转换为snake_case,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44745734/

相关文章:

c++ - C++ 运算符的速度/简单的数学运算

c - C中一个字符的大小

c - 访问 C 中对象的字节

java - 类型信息如何存储在内存中(如果有的话)

javascript - 是否可以以非递归方式遍历 JavaScript 中的对象?

computer-science - 列出涵盖典型 CS 本科生主题的书籍 list

c - 如何将数组的值设置为单个变量

c - do-while 没有按预期工作

opencv - 机器学习 : sign visibility

java - Eclipse 上的 JOptionPane 错误