根据条件从字符串中提取子字符串
我有一个格式为:[email protected] [email protected] ... [email protected]
的输入字符串。它总是由'@'
和' '
分隔。根据条件从字符串中提取子字符串
实施例:
[email protected] [email protected] [email protected]
它应该显示具有最小值的人的姓名。
如何解决?
输出:
driver
您可以结合使用strtok
和sscanf
函数来解决您的问题。
首先,您必须使用' '
(空格)作为分隔符来标记字符串,然后从每个标记中提取数字以查找具有最小编号的标记。每当您找到一个数字小于当前值的令牌时,从该令牌中提取名称并存储新的可能最小的数字。下面是一个例子:
#include <string.h>
#include <stdio.h>
#include <float.h>
int main() {
char str[] = "[email protected] [email protected] [email protected]";
char result[256] = { 0 };
char *token, *sep_ptr;
float value, min = FLT_MAX; /* set 'min' to the maximum of float */
/* tokenize 'str' and walk through the tokens */
for(token = strtok(str, " "); token != NULL; token = strtok(NULL, " ")) {
value = FLT_MAX;
/* process the current token if it contains a '@' character */
if(sep_ptr = strchr(token, '@')) {
sscanf(sep_ptr, "@%f", &value); /* extract value */
/* check if the new number is smaller than current 'min' */
if(value < min) {
strcpy(result, (*sep_ptr = '\0', token)); /* extract name */
min = value;
}
}
}
puts(result);
return 0;
}
代码的(*sep_ptr = '\0', token)
部分上面简单地替换'@'
字符执行复制从token
到result
之前空字符。 (所提到的表达式使用comma operator。)
下面的代码实现一个getSubstrSmallestNumber()
函数,它使用strtok()
函数而变化的输入缓冲器。如果你不希望你可以先复制字符串。改变输入缓冲区的好处是,找到的子字符串不需要内存分配。 strtok()
写入一个空终止符'\0'
,如果它被调用,则会找到指定的分隔符。
getSubstrSmallestNumber()
函数可以用特定的分隔符来调用,这里是'@'
和' '
。每个号码将被转换成双倍数,并且检查它是否比以前小。如果它更小,相应的令牌将被保存。 while循环结束后(如果strtok()
未找到更多标记),将返回保存的标记(最小双精度值)。
请注意,代码没有错误检查这应该被认为是实施以及。
的完整代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
char* getSubstrSmallestNumber(char* input, char* numberDelimiter, char* strDelimiter)
{
char* tokenStr;
double minNumber = DBL_MAX;
char* minToken = NULL;
for (tokenStr = strtok(input, numberDelimiter);
tokenStr != NULL;
tokenStr = strtok(NULL, numberDelimiter))
{
char* numberStr = strtok(NULL, strDelimiter);
double number = strtod(numberStr, NULL);
if (number < minNumber)
{
minNumber = number;
minToken = tokenStr;
}
}
return minToken;
}
int main()
{
char input[] = "[email protected] [email protected] [email protected]";
printf("<%s>\n", getSubstrSmallestNumber(input, "@", " "));
return 0;
}
输出:
<driver>
我把'<'
和'>'
串围在printf()
调用显示,getSubstrSmallestNumber()
返回的字符串实际上只是driver
,没有什么比如空间。
你可以使用strrok
可用的C字符串库和解析浮点数,你可以使用atof
函数但atof函数seems to be unreliable in some cases,不过。在这种情况下,您可以根据自己的需求编写自己的实现。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <float.h>
#define SIZE 1000
int main() {
char input[SIZE], smallest[SIZE], name[SIZE];
const char s[2] = "@";
char *token;
float val = FLT_MAX;
while(scanf("%s", input) != EOF) {
token = strtok(input, s);
strcpy(name, token);
token = strtok(NULL, s);
float curVal = atof(token);
if(curVal < val) {
val = curVal;
strcpy(smallest, name);
}
}
printf("Smallest value : %s\n", smallest);
return 0;
}
当我测试它似乎表明正确的输出:
~/Documents/src : $ ./a.out
[email protected]
[email protected]
[email protected]
Smallest value : driver
希望帮助!
您需要更具体。你知道弦的数量吗?这会输入还是在字符串缓冲区中?定界符是否总是@?以前的字符串是否只包含字符? –
其实这个问题没有指定我们需要计算的输入数量,下面是问题的输入,@是上面指定的每种情况的分隔符。 –
将主字符串分隔为带有分隔符“'''的子字符串,然后用分隔符”@“进一步分隔这些子字符串,该分隔符给出名称和数字(在此处使用双数组)。查找最高数字索引并显示名称数组中相应的名称)。使用你自己的一段代码来分隔使用分隔符。 此外,你甚至可以解决它,而不需要两个数组(一个名称和其他双打)。这取决于你如何编写代码(时间vs空间) –