我编写的程序分类如23.44 12.4223。几乎所有的一切都运行良好,但它没有正确的数字排序,例如24.321和24.33我的意思是我的rpgoram 24.321大于24.33
Infile包含34.5 123.55之类的数字。 56.43 564.3
这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define NUMBER_CHUNK 13
char* getNumber(FILE* fp)
{
int length;
int current = 0;
int c;
char *number, *number2;
number = (char*)malloc(sizeof(char)*NUMBER_CHUNK);
if(!number)
{
printf("Error while allocating memory!\n");
return NULL;
}
length = NUMBER_CHUNK;
while(!isspace(c = fgetc(fp)) && !feof(fp))
{
if(isdigit(c) || c == '.')
{
number[current] = c;
current++;
if(current >= length)
{
length+=NUMBER_CHUNK;
number2 = (char*)realloc(number,sizeof(char*)*length);
if(number2 == NULL)
{
free(number2);
return NULL;
}
else number2 = number;
}
}
else
{
return NULL;
}
}
number[current] = '\0';
return number;
}
int compare(const void *str1, const void *str2)
{
char* curr1;
char* curr2;
int value = 0;
size_t len1 = 0;
size_t len2 = 0;
curr1=*(char**)str1;
curr2=*(char**)str2;
while(*curr1=='0' || *curr1=='.') curr1++;
while(*curr2=='0' || *curr2=='.') curr2++;
while(*curr1 || *curr2)
{
while(*curr1 == '.')
curr1++;
while(*curr2 == '.')
curr2++;
if(value == 0)
{
value = *curr1 - *curr2;
}
if(*curr1)
{
curr1++;
len1++;
}
if(*curr2)
{
curr2++;
len2++;
}
}
if(len1 != len2)
{
return (len1 > len2) ? 1 : -1;
}
return value;
}
int main(int argc, char** argv)
{
FILE* fp;
char** tab;
int i = 0;
int lines = 0;
int length = 10;
if(argc != 2)
{
printf("Incorrent syntax! Use ./program_name input_file\n");
return 1;
}
if(!(fp = fopen(argv[1],"r")))
{
printf("Could not open the file! Please try again!\n");
return 2;
}
tab = (char**)malloc(length*(sizeof(char*)));
if(!tab)
{
printf("Could not allocate memory!\n");
free(tab);
return 3;
}
while(!feof(fp))
{
tab[i] = getNumber(fp);
if(i >= length)
{
length += 10;
tab = (char**)realloc(tab,sizeof(char*));
if(tab == NULL)
{
free(tab);
return 5;
}
}
if(tab[i] == NULL)
{
printf("Incorrect character in the infile! Terminating\n");
free(tab);
return 4;
}
if(*tab[i] == '\0')
{
free(tab[i]);
i--;
}
i++;
lines = i;
}
printf("\nBEFORE\n");
for(i = 0 ; i < lines; i++)
{
printf("%s\n", tab[i]);
}
qsort(tab, lines, sizeof(char*), compare);
printf("\nAFTER\n");
for(i = 0; i < lines; i++)
{
printf("%s\n",tab[i]);
free(tab[i]);
}
printf("\n");
free(tab);
fclose(fp);
return 0;
}
答案 0 :(得分:1)
在您的计划中24.321
大于24.33
,因为24.321
的长度大于24.33
的长度。
阅读.
时,您应该停止增加长度。
修正:
//UPDATE
while(*curr1=='0') curr1++;
while(*curr2=='0') curr2++;
//END OF UPDATE
char dot1 = 0, dot2 = 0;
char err1 = 0, err2 = 0;
while(*curr1 || *curr2)
{
if(*curr1 == '.') ++dot1; //UPDATE2
if(*curr2 == '.') ++dot2; //UPDATE2
while(*curr1 == '.')
curr1++;
while(*curr2 == '.')
curr2++;
if(value == 0)
{
value = *curr1 - *curr2;
}
if(*curr1)
{
if(*curr1 < '0' || *curr1 > '9') err1 = 1;
curr1++;
if(!dot1) len1++;
}
if(*curr2)
{
if(*curr2 < '0' || *curr2 > '9') err2 = 1;
curr2++;
if(!dot2) len2++;
}
}
if(err1 || err2 || dot1 > 1 || dot2 > 1) exit(1); // UPDATE2
更新:
我更新了代码。现在在主要比较之前,只跳过零。在主要开始时将跳过点,并使用dot1
和dot2
进行修复。
UPDATE2: 要检查数字是否正确,您应计算点数并检查所有字符是否为点或数字。 请注意,对于较长的错误数字(超过255个点),我的代码无法正常工作(因为dot1长度为1个字节)。如果你需要处理这些情况,你应该检查dot1 / dot2是否等于1并将err1 / err2改为1而不是增加dot1 / dot2。
答案 1 :(得分:0)
你的问题在这里:---
if(len1 != len2)
{
return (len1 > len2) ? 1 : -1;
}
对于字符串“24.321”len1 = 6,“24.33”len2 = 5所以最长的字符串获胜。
我认为你的算法也会遇到123.45 vs 23.456的问题,因为你基本上忽略了小数点。
您可以尝试转换为浮点(使用函数atof()或strtof())将字符串转换为实数,然后进行比较。
如果遇到“。”,只需返回“小于”。在第二个字符串中遇到它之前的第一个字符串中。