根据条件从字符串中提取子字符串
Extract sub string from a string based on a condition
我有一个格式为:name1@float1 name2@float2 ... nameN@floatN
的输入字符串。它始终由 '@'
和 ' '
.
分隔
示例:
ash@19.96 ram@12.3 driver@10.2
它应该显示具有最小值的人的名字。
如何解决?
输出:
driver
以下代码实现了一个 getSubstrSmallestNumber()
函数,该函数使用 strtok()
function which changes the input buffer. If you don't want that you can first copy the string. The good point about changing the input buffer is that no memory allocation is needed for the found sub string. The strtok()
写入空终止符 '[=15=]'
,如果调用它,则在其中找到指定的定界符。
getSubstrSmallestNumber()
函数可以使用特定的分隔符调用,这里是 '@'
和 ' '
。每个数字都将转换为双精度,strtod()
and checked if it smaller than before. If it's smaller the corresponding token will be saved. After the while loop finished (if 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[] = "ash@19.96 ram@12.3 driver@10.2";
printf("<%s>\n", getSubstrSmallestNumber(input, "@", " "));
return 0;
}
输出:
<driver>
我在 printf()
调用中将 '<'
和 '>'
放在字符串周围,以表明 getSubstrSmallestNumber()
返回的字符串实际上只是 driver
和例如 space。
您可以使用 C 字符串库中可用的 strrok
,对于解析浮点数,您可以使用 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
ram@12.3
driver@10.2
ash@19.96
Smallest value : driver
希望对您有所帮助!
您可以组合strtok
and sscanf
个函数来解决您的问题。
首先,您必须使用 ' '
(white-space) 作为分隔符来标记您的字符串,然后从每个标记中提取数字以找到数字最小的标记。每次找到一个比当前数字小的标记时,从该标记中提取名称并存储新的可能最小的数字。这是一个例子:
#include <string.h>
#include <stdio.h>
#include <float.h>
int main() {
char str[] = "ash@19.96 ram@12.3 driver@10.2";
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 = '[=10=]', token)); /* extract name */
min = value;
}
}
}
puts(result);
return 0;
}
上面代码的(*sep_ptr = '[=14=]', token)
部分只是在执行从token
到result
的复制之前将'@'
字符替换为空字符。 (上述表达式使用 comma operator。)
我有一个格式为:name1@float1 name2@float2 ... nameN@floatN
的输入字符串。它始终由 '@'
和 ' '
.
示例:
ash@19.96 ram@12.3 driver@10.2
它应该显示具有最小值的人的名字。
如何解决?
输出:
driver
以下代码实现了一个 getSubstrSmallestNumber()
函数,该函数使用 strtok()
function which changes the input buffer. If you don't want that you can first copy the string. The good point about changing the input buffer is that no memory allocation is needed for the found sub string. The strtok()
写入空终止符 '[=15=]'
,如果调用它,则在其中找到指定的定界符。
getSubstrSmallestNumber()
函数可以使用特定的分隔符调用,这里是 '@'
和 ' '
。每个数字都将转换为双精度,strtod()
and checked if it smaller than before. If it's smaller the corresponding token will be saved. After the while loop finished (if 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[] = "ash@19.96 ram@12.3 driver@10.2";
printf("<%s>\n", getSubstrSmallestNumber(input, "@", " "));
return 0;
}
输出:
<driver>
我在 printf()
调用中将 '<'
和 '>'
放在字符串周围,以表明 getSubstrSmallestNumber()
返回的字符串实际上只是 driver
和例如 space。
您可以使用 C 字符串库中可用的 strrok
,对于解析浮点数,您可以使用 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
ram@12.3
driver@10.2
ash@19.96
Smallest value : driver
希望对您有所帮助!
您可以组合strtok
and sscanf
个函数来解决您的问题。
首先,您必须使用 ' '
(white-space) 作为分隔符来标记您的字符串,然后从每个标记中提取数字以找到数字最小的标记。每次找到一个比当前数字小的标记时,从该标记中提取名称并存储新的可能最小的数字。这是一个例子:
#include <string.h>
#include <stdio.h>
#include <float.h>
int main() {
char str[] = "ash@19.96 ram@12.3 driver@10.2";
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 = '[=10=]', token)); /* extract name */
min = value;
}
}
}
puts(result);
return 0;
}
上面代码的(*sep_ptr = '[=14=]', token)
部分只是在执行从token
到result
的复制之前将'@'
字符替换为空字符。 (上述表达式使用 comma operator。)