将十六进制数转换为十进制格式

时间:2016-11-05 10:53:59

标签: c csv hex

此代码读取带有十六进制格式数字的csv文件,将其转换为十进制格式并将十进制数字写入另一个文件。

/* Author: Madalina Erascu*/
/* Input:  csv file with numbers in hexa fomat
   Output: csv file with numbers in decimal fomat with 80 decimals
   Usage: main list_input_files list_output_files
   Attention: function hex2double - the specifier llx might not give the same output on computers with other OS than Windows, MinGW compiler, etc.
*/
#include <stdio.h>
#include <stdlib.h>

long double hex2double(const char *);

int main(int argc, char *argv[])
{
   char buffer[1024] ;
   char *record,*line;
   long double x;
   int i,j;

   printf( "argc = %d\n", argc );
   for( i = 1; i <= argc/2; ++i ) {
       printf( "argv[ %d ] = %s\n", i, argv[ i ] );
       printf( "argv[ %d ] = %s\n", (argc/2) + i, argv[ (argc/2) + i ] );

       FILE *fstream_in =  fopen(argv[  i           ],"r");
       FILE *fstream_out = fopen(argv[ (argc/2) + i ],"w");

       if(fstream_in == NULL) {
            printf("\nFile opening failed:", fstream_in);
            return -1 ;
       }

       int idx = 0;

       while((line=fgets(buffer,sizeof(buffer),fstream_in))!=NULL) {
            record = strtok(line,",");
            while(record != NULL) {
                    idx++;
                    printf("String : %d|%s|\n",idx,record) ;
                    x = hex2double(record) ;
                    fprintf(fstream_out,"%.80e\n", x);
                    record = strtok(NULL,",");
            }
       }
    }
    return 0 ;
    }

long double hex2double(const char *s)
{
    long double d = 0.0;
    sscanf(s, "%llx",  &d);

    return d;
}

当我在此链接上使用该文件作为输入时:

https://dl.dropboxusercontent.com/u/64621064/trigon_batch2.csv

文件中的第61个数字分为2个数字。 hexa格式的数字实际上是浮点数,而不是整数......

有任何解释吗?

1 个答案:

答案 0 :(得分:0)

  1. 请勿使用sscanf(),请使用strtoll()代替此

    return (double) strtoll(s, NULL, 16);
    

    如果您想检查错误,请将非NULL指针作为endptr传递并检查未转换的字符,您也可以使用sscanf()进行检查,但它不是适合这种情况。

    另外,我不会写这样的代码。我只是帮你修复你的问题,我认为这样做。虽然如果你在没有任何小数值的情况下读取整数就没有意义,那么转换为double是没有意义的。

  2. 你遇到的另一个问题是

    printf("\nFile opening failed:", fstream_in);
    

    出于多种原因这是错误的:

    • NEW LINE字符用于控制stdio输出函数的缓冲,它们被称为行缓冲,因此,'\n'字符“刷新“缓冲区,因此将它放在一行的末尾是有意义的。

    • 它是UNDEFINED BEHAVIOR,因为您将参数传递给printf(),但没有说明符,如果您想要一条消息告诉用户文件没有打开,请传递文件名此

      printf("failure opening %s\n", argv[i]);
      
  3. 您还应该检查您打开的文件是否针对NULL进行编写,fopen()失败的唯一原因并不是该文件不存在。考虑没有在目标目录中写入的权限,它也将返回NULL,然后您的代码将调用UNDEFINED BEAVAVIOR。