此代码读取带有十六进制格式数字的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格式的数字实际上是浮点数,而不是整数......
有任何解释吗?
答案 0 :(得分:0)
请勿使用sscanf()
,请使用strtoll()
代替此
return (double) strtoll(s, NULL, 16);
如果您想检查错误,请将非NULL
指针作为endptr
传递并检查未转换的字符,您也可以使用sscanf()
进行检查,但它不是适合这种情况。
另外,我不会写这样的代码。我只是帮你修复你的问题,我认为这样做。虽然如果你在没有任何小数值的情况下读取整数就没有意义,那么转换为double是没有意义的。
你遇到的另一个问题是
printf("\nFile opening failed:", fstream_in);
出于多种原因这是错误的:
NEW LINE字符用于控制stdio输出函数的缓冲,它们被称为行缓冲,因此,'\n'
字符“刷新“缓冲区,因此将它放在一行的末尾是有意义的。
它是UNDEFINED BEHAVIOR,因为您将参数传递给printf()
,但没有说明符,如果您想要一条消息告诉用户文件没有打开,请传递文件名此
printf("failure opening %s\n", argv[i]);
您还应该检查您打开的文件是否针对NULL
进行编写,fopen()
失败的唯一原因并不是该文件不存在。考虑没有在目标目录中写入的权限,它也将返回NULL
,然后您的代码将调用UNDEFINED BEAVAVIOR。