在C代码中读取数据以分号分隔的CSV文件

yebdmbv4  于 2023-04-27  发布在  其他
关注(0)|答案(1)|浏览(142)

我有以下格式的测量数据:
40.0095;34.0;;0.065058;;392;300;;;;;;;;;;; 40.0242;;14.8;;;;;;392;300;400;300;20.0;0.0;0.0;-0.0;0.3;-0.3;1444;1494;392.9;18.6;299.7;-4.4
等等。
我尝试使用fscanf阅读文件,但它不读取值。而是记录0.0。
下面是我的代码:

# include <stdio.h>
# include <string.h>

double t_abs[700] ;
double t_nxtSIO[700] ;

int main( )
{
    FILE *filePointer ;
    
    filePointer = fopen("BallPlateLogData.txt", "r") ;

    if ( filePointer == NULL )
    {
        printf( "file failed to open." ) ;
    }
    else
    {
        int read = 0 ;
        int line = 0 ;
        
        printf("The file is now opened.\n") ;
        
        do{

        if (line != 0)
        {
            read = fscanf(filePointer,
                           "%lf[^;], %lf[^;]\n",
                            t_abs[line],
                            t_nxtSIO[line]) ;
        }

        line++ ;

        if (ferror(filePointer))
        {
            printf("Error reading file\n");
            return 1 ;
        }

        fclose(filePointer) ;
    
    printf("%0.1f\n", t_abs[line]) ;

    } while (!feof(filePointer)) ;
   
    }

    return 0;   
}

上面的不起作用。
帮助是非常感谢!

aurhwmvo

aurhwmvo1#

scanf可以很好地阅读格式化的输入。如果你的输入可能包含空字段,那么它就不是真正的格式化,scanf是错误的工具。也许可以让scanf工作,但它会比它的价值更难。相反,你可以用fgets读取每一行,并用strtod解析数据。例如:

#include <stdio.h>                                                                 
#include <stdlib.h>                                                                
#include <ctype.h>                                                                 
#include <string.h>                                                                
                                                                                   
double t_abs[700] ;                                                                
double t_nxtSIO[700] ;                                                             
                                                                                   
double                                                                             
parse_input(char *b, char **cursor, int line, int expect)                          
{                                                                                  
        char *start = *cursor;                                                     
        char **end = cursor;                                                       
                                                                                   
        double val = strtod(start, end);                                           
        while(isspace(**end)){  /* Skip over whitespace */                         
                *end += 1;                                                         
        }                                                                          
        if( **end != expect ){  /* Match the delimiter */                          
                fprintf(stderr, "Unexpected input in line %d:\n", line + 1);       
                fprintf(stderr, "%s", b);                                          
                while( b++ < *end ){                                               
                        putc(' ', stderr);                                         
                }                                                                  
                fprintf(stderr, "^^^^\n");                                         
                exit(1);                                                           
        }                                                                          
        *end += 1;         /* Move past the delimiter */                           
        return val;                                                                
}    
                                                                                   
int                                                                                
main(int argc, char **argv)                                                        
{                                                                                  
        FILE *filePointer ;                                                        
        char buf[1024];                                                            
        filePointer = argc > 1 ? fopen(argv[1], "r") : stdin;                      
        if( filePointer == NULL ) {                                                
                perror(argc > 1 ? argv[1] : "stdin");                              
                return 1;                                                          
        }                                                                          
        int line = 0 ;                                                             
        while( line < 700 && fgets(buf, sizeof buf, filePointer) != NULL ){        
                if( line != 0 ) {                                                  
                        char *cursor = buf;                                        
                        char *end;                                                 
                        t_abs[line] = parse_input(buf, &cursor, line, ';');        
                        t_nxtSIO[line] = parse_input(buf, &cursor, line, ';');     
                }                                                                  
                line += 1;                                                         
        }                                                                          
        fclose(filePointer) ;                                                      
        for( int i = 1; i < line; i += 1 ){                                        
                printf("%0.1lf  %0.1lf \n", t_abs[i], t_nxtSIO[i]) ;               
        }                                                                          
        return 0;                                                                  
}

这段代码的目的是希望你将'\n'作为expect参数传递给输入的最后一个字段,但是这不会像现在这样工作,因为isspace会超过换行符。这和你在scanf中遇到的问题是完全一样的,所以在显式的情况下弄清楚如何处理它可能是一个很好的练习。
另外要注意的是,数组是从零开始的,你从第二行输入的数据写入数组的索引1,而没有将任何数据放入数组的第一个位置(索引0),这看起来很奇怪。

相关问题