我想要编码的是,如果我输入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
调用这些函数。 。我知道,这有点复杂。解决此问题的另一种方法是始终转换您的 char
至unsigned 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/