我在解析c中的用户输入时遇到了麻烦。我的任务(作业)是读取用户输入,然后以与BASH相同的方式解析,因此分隔符是'',|,>等等。到目前为止我的(错误)解决方案使用strtok。我被建议使用sscanf,但是我无法理解它将如何适用于所有用户输入的情况。
我喜欢一种能让我指向正确方向的策略。这是我到目前为止所做的:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define MAX_LINE 80
int main ()
{
const char delim[]=" \\|\\>\\1>\\2>\\>>\\2>>\\&>\\<";
char* args[MAX_LINE/2 + 1];
char tok[MAX_LINE];
char* token;
printf("osh>");
fgets(tok, sizeof(tok), stdin);
token = strtok(tok,delim);
while (token != NULL)
{
printf("%s\n", token);
token = strtok(NULL, delim);
}
return 0;
}
答案 0 :(得分:2)
方法1) 您可以使用指针算法来定位分隔符,同时仍然使用strtok来提取分隔的字符串。在我看来,这是最简单的解决方案,但需要pointer arithmetic。请确保您不要尝试访问数组末尾或数组之前的“tok”(通过过度递减指针)。
示例:
token = strtok(tok, delim);
char verb = *token--;
方法2) 您可以以相同的方式使用sscanf查找字符串,然后单个字符,然后是字符串......依此类推,直到您到达行尾。
对于任何一种方法,您需要将字符串和分隔符存储在某处并维护顺序,以便重新构建序列。
祝你好运。答案 1 :(得分:0)
感谢您的帮助。我最终完全走了一条不同的路线,基本上跟踪了fgets结果的每个索引的内容,然后从那里解析。我没有最终使用任何c-ish方法(即strtok)来完成这项工作。
这是一个示例代码段。
{
//integers correspond to ASCII values
LEN++;
if ((line[i+1] == 60) || (line[i+1] == 62) || (line[i+1] == 124) || (line[i+1] == 38) || (line[i+1] == 32) || (line[i+1] == 10))
{
memcpy(substring, &line[string_start], LEN);
substring[LEN] = '\0';
args[token_number] = malloc(strlen(substring) + 1);
strcpy(args[token_number], substring);
token_number++;
string_start = i+1;
LEN = 0;
}
i++;
}