我正试图弄清楚如何以多种方式读取输入。输入可以是这样的。
N:{-4,2,1}
E:{1,1,9}
W:{-2,5,3}
S:{7,1}
或者像这样
E:{9,1,1}N:{1,2,-4}W:{3,5,-2}S:{7,1}
我在我的代码中添加了单词END的检查。它应该是在EOF上工作的,但是在我的Windows机器上它不工作。所以输入END来表示输入的结束。到目前为止,我设法让它们都单独工作...但是我需要它们同时工作。
char *skip_whitespace(char *str)
{
//skip any leading whitespace characters
while (*str == ' ' || *str == '\t')
str++;
return str;
}
void read_tokens(int *north, int *west, int *east, int *south, int *north_size, int *west_size, int *east_size, int *south_size)
{
//buffer for reading in input
char buffer[MAX_TOKENS];
//read in the input line by line
while (fgets(buffer, MAX_TOKENS, stdin) != NULL)
{
//remove the newline character from the end of the line
buffer[strcspn(buffer, "\n")] = 0;
//check for the "END" string to end the input
if (strcmp(buffer, "END") == 0)
break;
//split the line at the curly brace character
char *direction_token = strtok(buffer, "{");
char *tokens = strtok(NULL, "}");
//get the direction
char direction = direction_token[0];
//skip any leading or trailing whitespace characters
tokens = skip_whitespace(tokens);
//split the tokens at each comma
char *token = strtok(tokens, ",");
//determine the direction and store the tokens in the appropriate array
if (direction == 'N')
{
while (token != NULL)
{
//skip any leading or trailing whitespace characters
token = skip_whitespace(token);
//store the token in the array
north[*north_size] = atoi(token);
(*north_size)++;
//find the next token
token = strtok(NULL, ",");
}
}
else if (direction == 'W')
{
while (token != NULL)
{
//skip any leading or trailing whitespace characters
token = skip_whitespace(token);
//store the token in the array
west[*west_size] = atoi(token);
(*west_size)++;
//find the next token
token = strtok(NULL, ",");
}
}
else if (direction == 'E')
{
while (token != NULL)
{
//skip any leading or trailing whitespace characters
token = skip_whitespace(token);
//store the token in the array
east[*east_size] = atoi(token);
(*east_size)++;
//find the next token
token = strtok(NULL, ",");
}
}
else if (direction == 'S')
{
while (token != NULL)
{
//skip any leading or trailing whitespace characters
token = skip_whitespace(token);
//store the token in the array
south[*south_size] = atoi(token);
(*south_size)++;
//find the next token
token = strtok(NULL, ",");
}
}
else
{
//invalid direction = error
printf("Nespravny vstup.\n");
}
}
}
这是主要的函数。对任何感兴趣的人来说都是调用和打印。
int main(void)
{
//field for token values
int north[MAX_TOKENS], west[MAX_TOKENS], east[MAX_TOKENS], south[MAX_TOKENS];
//sizes of token value fields
int north_size = 0, west_size = 0, east_size = 0, south_size = 0;
printf("Input:\n");
//fetch token values from input
read_tokens(north, west, east, south, &north_size, &west_size, &east_size, &south_size);
printf("N: { ");
for (int i = 0; i < north_size; i++)
printf("%d, ", north[i]);
printf("}\n");
printf("W: { ");
for (int i = 0; i < west_size; i++)
printf("%d, ", west[i]);
printf("}\n");
printf("E: { ");
for (int i = 0; i < east_size; i++)
printf("%d, ", east[i]);
printf("}\n");
printf("S: { ");
for (int i = 0; i < south_size; i++)
printf("%d, ", south[i]);
printf("}\n");
}
1条答案
按热度按时间gpfsuwkq1#
你有一个输入格式,允许在标记之间使用可选的空格,包括换行符。你的两个例子的不同之处仅仅在于一个使用了这个选项,而另一个没有。用最基本的术语来说,解决方案是让你的解析器也忽略标记之间的(所有)空格。这样的解析器可以处理两种形式的输入,也可以处理其他变体。
然而,我确实认为
fgets()
在这里更多的是一种负担而不是一种帮助。您的输入基本上不是面向行的,并且使用fgets()
时,您需要(但目前还不需要)注意和处理将一个长行拆分为两个或更多个读取的情况。我建议直接从流中对输入进行标记化,而不是首先将其读入中间缓冲区。我知道
scanf()
很不受欢迎,但它可能很好地满足了您的需求。它已经知道如何跳过空格、识别整数和匹配特定字符。也许可以这样做:如果你想避免
scanf()
,那么你可以通过getchar()
或fgetc()
一次阅读一个字符来做基本相同的事情,或者,是的,如果你足够小心的话,也可以用fgets()
。当然,这只是示意图,并不是所需解析器的完整实现