Extract string (C language)
Write a blog New Year's Eve (><) Happy New Year! Safe!
Directly on the picture:
When you look at this kind of topic, you know-it's so easy! A lot of pits! This damn detail!
- Pit 1: xxx.42xxx outputs 0.42
- Pit 2:
xxx123
456xxx outputs 123456
-xxx123
.456xx outputs 123.456 - Detail 1: How to extract numbers?
- Detail 2: How to sort floating-point numbers?
Gan, I stopped writing xxx, and under pressure, I still racked my brains and came out (Crying Haw,
don’t talk nonsense, go to the train of thought:
1. Preparation
- The end of multi-line input is judged by EOF, ie ctrl+z
- Open a two-dimensional array and store the extracted number string: m[j][k]
- Use the atof function to convert the string to a floating point number and store it in the double array num[35]. (Note that atof returns double, I thought it was a float and then I made an error)
- Use qsort to sort, notice:
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void *)) The
compar function returns an int type, so change its variant:
return *(double *)a < *(double *)b ? 1 : -1;
2. The main part
- Use the isdigit function to determine whether it is a number and start to extract
- If the last of the line is a number, set a flag:
f = 1;
hand it over to the next line, and judge whether the beginning of the next line is a number, then continue to add (k) to the end of the original extracted number, and withdraw the increment of the number of numbers (j) :
k += 1; j -= 1;
- If you encounter a number, add 0 at the beginning, then switch to the extraction of numbers, and set a flag as well:
f1 = 1;
3. Code part
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
int j=0, k=0, f=0, f1=0, sum=0;
char m[35][25] = {
"0"}; //m[j][k]数字字符串数组,j为数字的个数,k为数字的长度
double num[35] = {
0};
int cmp(const void *a, const void *b) //降序排序
{
return *(double *)a < *(double *)b ? 1 : -1;
}
double *find(char str[])
{
int n, a=0, i=0;
n = strlen(str);
for(i = 0; i < n; i++)
{
if(i == 0) //判断上一行是否为数字 是f=1
{
if(f && (isdigit(str[i]) || str[i] == '.')) //该行开头为数字或小数点
{
k += 1; //接在上一行提取的数字后面
j -= 1; //不要递增,还是上一个提取的数
if(str[i] == '.')
{
m[j][k] = str[i];
k++;
} //此时f未归0,为了避免与.数字的情况冲突
}
else //如果该行开头不是数字或小数点,归0
{
k = 0;
f = 0;
}
}
if(!(isdigit(str[i-1])) && str[i] == '.' && f == 0) //出现.数字的情况,接下来处理为0.数字
f1 = 1;
if(isdigit(str[i]) || f1 == 1) //如果是数字或者是.数字
{
f = 0; //将可能未归0的f归0
if(f1 == 1)
{
m[j][k] = '0'; //加0
k++;
f1 = 0;
}
m[j][k] = str[i]; //存第一个数字
i++;
if(i == n) //如果是一行的最后一位
{
f = 1;
j++; //默认存完一串数字就递增
}
for(a = i; a < n; a++) //存接下来的数字
{
if(isdigit(str[a]) || (str[a] == '.' && isdigit(str[a+1]))) //第二个括号判断条件舍去了数字.的情况
{
k++;
m[j][k] = str[a]; //存
if(a == n-1) //直到一行最后一位
{
j++;
f = 1;
}
}
else //存结束了
{
k = 0;
j++;
i = a-1;
break;
}
}
}
if(a == n) //如果a增到结尾,就让i跳出循环,避免重复计算
i = n-1;
}
for(i = 0; i < j; i++) //字符串转为浮点数
num[i] = atof(m[i]);
return num;
}
int main(void)
{
char str[1000] = {
"0"};
while(scanf("%s",str)!=EOF)
find(str);
qsort(num, j, sizeof(num[0]), cmp);
printf("%.2f",num[0]);
for(int i = 1; i < j; i++)
printf(" %.2f",num[i]);
printf("\n");
return 0;
}