gpt4 book ai didi

c - C中的unicode字符串比较

转载 作者:太空宇宙 更新时间:2023-11-03 23:20:54 28 4
gpt4 key购买 nike

我正在学习 UNIX 系统编程。我正在为 UNIX 编写一个简单的 shell 应用程序(我在 OS X Yosemite ver 10.10.5 上使用 Xcode)。我有一些使用 C 语言的经验,但不多。

实用程序工作正常并且会打印 unicode 字符(虽然 ls 在 Xcode 控制台中打印 '????' 而不是它,但这似乎是调试器本身的问题)。

我做了一些研究,发现 strcmp() 应该也能正常工作,因为它只是比较字节并在最后查找零字节。读取输入也应该没问题,因为您只读取字节。

我还读到 unicode 字符串不应包含空字节。但是,在执行 `strcmp() 时,某些输入会导致 EXC_BAD_ACCESS

代码:

读取用户输入:

char* readCommand(void) {
int buffer_size = LINE_BUFFER_SIZE;
char *buffer = malloc(sizeof(char) * buffer_size);
int position = 0;
int character;

if(!buffer)
{
fprintf(stderr, "readCommand failed: memory allocation error");
exit(ALLOCATION_ERROR);
}

while (1) {
character = getchar();
if(character == EOF || character == '\n')
{
buffer[position] = '\0';
char* cmd = buffer;
free(buffer);
return cmd;
}
else {
buffer[position] = character;
}
if(++position >= sizeof(buffer))
{
buffer_size += LINE_BUFFER_SIZE;
buffer = realloc(buffer, sizeof(char) * buffer_size);
if(!buffer) {
fprintf(stderr, "readCommand failed: memory reallocation error");
free(buffer);
exit(ALLOCATION_ERROR);
}
}
}
return NULL;
}

拆分参数:

int split_string_quotes(char* source, char** argv, size_t arg_count)
{
enum split_states state = DULL;
char* p, *word_start = NULL;
int character;
int argc = 0;
for(p = source; argc < arg_count && *p != '\0'; p++)
{
character = (unsigned char) *p;
switch (state) {
case DULL:
if(isspace(character))
{
continue;
}
if(character == '"')
{
state = IN_STRING;
word_start = p+1;
continue;
}
state = IN_WORD;
word_start = p;
continue;

case IN_WORD:
if(isspace(character))
{
state = DULL;
*p = 0;
argv[argc++] = word_start;
}
continue;

case IN_STRING:
if(character == '"')
{
state = DULL;
*p = 0;
argv[argc++] = word_start;
}
continue;
}
}

if(state != DULL && argc < arg_count)
{
argv[argc++] = word_start;
}
argv[argc] = NULL;
return argc;
}

这就是 strcmp 所在的地方:

int shell_execute(char **args)
{
for(int i = 0; i < 3; i++)
{
if(strcmp(args[0], commands[i]) == 0)
{
return (*standardFuncs[i])(args);
}
}
shell_launch(args);
return 0;
}

主循环

    char* current_dir = malloc(sizeof(char)*PATH_MAX);
char* args[MAX_ARGS];
char* command;
printf("dolphinShell (c) Alex Kale 2016\n");
while (1)
{
getwd(current_dir);
printf("dsh: %s-> ", current_dir);
command = readCommand();
printf("%s\n", command);
split_string_quotes(command, args, MAX_ARGS);
if(shell_execute(args) == -1) break;
}
free(current_dir);
return 0;

所以,问题是我输入的一些 unicode 字符串工作正常并且永远不会导致 EXC_BAD_ACCESS,但是当我输入 фывпфвыапы 时,例如,它会中断。我认为问题在于访问 args[0],但这是调试器的输出:

 Printing description of args:
(char **) args = 0x00007fff5fbff900
*args char * 0x101800a00 0x0000000101800a00
Printing description of *(*(args)):
(char) **args = '\xd1'

所以它认为args[0]是空的,但是它是空的吗?还是被所有的零混淆了?

我真的很困惑,我花了很多时间研究并且似乎被困在这里。

我也尝试过使用 wchar_twcscmp(),但它不适用于 execvp()解决问题。

我也尝试过 gcc -Wall -Wextra,这是输出:

main.c:53:26: warning: comparison of integers of different signs: 'int' and
'size_t' (aka 'unsigned long') [-Wsign-compare]
for(p = source; argc < arg_count && *p != '\0'; p++)
~~~~ ^ ~~~~~~~~~
main.c:92:30: warning: comparison of integers of different signs: 'int' and
'size_t' (aka 'unsigned long') [-Wsign-compare]
if(state != DULL && argc < arg_count)
~~~~ ^ ~~~~~~~~~
main.c:124:23: warning: comparison of integers of different signs: 'int' and
'unsigned long' [-Wsign-compare]
if(++position >= sizeof(buffer))
~~~~~~~~~~ ^ ~~~~~~~~~~~~~~
main.c:180:18: warning: unused parameter 'args' [-Wunused-parameter]
int dHelp(char **args)
^
main.c:203:18: warning: unused parameter 'args' [-Wunused-parameter]
int dExit(char **args)
^
main.c:210:14: warning: unused parameter 'argc' [-Wunused-parameter]
int main(int argc, const char** argv)
^
main.c:210:33: warning: unused parameter 'argv' [-Wunused-parameter]
int main(int argc, const char** argv)
^
7 warnings generated.

但我认为情况并非如此(如果我错了请纠正我)。

最佳答案

显示的代码中存在多个错误。

        char* cmd = buffer;
free(buffer);
return cmd;

这将返回指向已删除的 char 缓冲区的指针。继续使用此指针会导致未定义的行为。

        if(++position >= sizeof(buffer))

buffer 是一个 char *。这相当于:

        if(++position >= sizeof(char *))

这将是 4 或 8 个字节,具体取决于您的硬件平台。每当缓冲区大于 4 或 8 字节时,这都会不必要地调整缓冲区大小。

您似乎相信 sizeof() 给出了 malloc 缓冲区的大小。它没有。

总而言之:您在这里的总体方法是编写一大堆代码,然后尝试查看它是否能正常工作。这是错误的做法。您需要编写一个小函数。例如将一行读入缓冲区的那个。测试它。验证它是否有效。现在您知道它可以工作了,继续并编写整个程序的下一小部分。

关于c - C中的unicode字符串比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40041603/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com