如何用.txt文件中的元素填充数组



我有一个动态二维浮点数组和一个文件,其中包含字符串,整数(行中浮点数)和浮点数。

M = (float**)malloc(num_lines * sizeof(float));
for(int i = 0; i < num_lines; i++){
M[i] = (float*)malloc(num_columns * sizeof(float));
}

的例子:

2
John 3 5.5 89.5 30.67 0.00
Mary 4 78.9 67.4 67.3 9.0 0.00
(null)

行数是文件上的行数+ 1,列数是最大的整数+ 1(在本例中是5),因为0.00标志着每行的结束。我如何加载只有浮动到内存中?我已经尝试了不同类型的循环与fgetsstrtok,但它不工作,由于不同类型的变量。

代码如下:

for(int i = 0; i < num_lines; i++){
fgets(buf, 1000, aux);
name = strtok(buf, " ");
col = atoi(strtok(NULL, " "));
for(j = 0; j < num_columns; j++){  
M[i][j] = atof(strtok(NULL, " "));
if(M[i][j] == 0.00){
break;
}   
}
}

这种解析有点麻烦,但这是一个很好的练习,可以不时地做一下。这是相对容易与scanf,但scanf不适合任何东西,除了玩具。(实际上不可能健壮地正确处理任何事情,因为即使是简单的"%d"格式说明符也会导致某些输入的未定义行为。)除非您愿意读取文件两次以确定列的最大大小,否则您不能预先分配整个数组。相反,我建议这样做:

#include <ctype.h>                                                                 
#include <err.h>                                                                   
#include <stdio.h>                                                                 
#include <stdlib.h>                                                                
#include <string.h>                                                                
             
/* sample input                                                                    
2                                                                                  
John 3 5.5 89.5 30.67 0.00                                                         
Mary 4 78.9 67.4 67.3 9.0 0.00                                                     
*/                                                                                 
FILE * xfopen(const char *, const char *);                                         
void * xmalloc(size_t);                                                            
int get_row_count(FILE *in, char **line, size_t *cap, const char *name);           
float * parse_line(const char *s, int lc);                                         
             
int                                                                                
main(int argc, char **argv)                                                        
{                                                                                  
int lc = 0;                                                                
char *line = NULL;                                                         
size_t cap = 0;                                                            
FILE *in = argc > 1 ? xfopen(argv[1], "r") : stdin;                        
             
int rows = get_row_count(in, &line, &cap, argv[1]);                        
float **M = xmalloc(rows * sizeof *M);                                     
for( lc = 0; lc < rows && getline(&line, &cap, in) > 0; lc += 1 ){         
M[lc] = parse_line(line, lc + 1);                                  
}                                                                          
if( lc != rows ){                                                          
warnx("invalid input: missing some rows");                         
}                                                                          
for( int i = 0; i < lc; i++ ){                                             
float *f = M[i];                                                   
for( int j = 0; j < f[0]; j++ ){                                   
printf("%ft", f[j + 1]);                                  
}                                                                  
putchar('n');                                                     
}                                                                          
}                                                                                  
             
float *                                                                            
parse_line(const char *s, int lc)                                                  
{                                                                                  
/* Skip the name */                                                        
char *end;                                                                 
while( *s && ! isspace(*s) ){                                              
s += 1;                                                            
}                                                                          
int siz = strtol(s, &end, 10);                                             
if( siz <= 0 || ! isspace(*end) ){                                         
errx(EXIT_FAILURE, "Invalid input on line %d", lc);                
}                                                                          
float *f = xmalloc((1 + siz) * sizeof *f);                                 
f[0] = siz;                                                                
             
for( int i = 1; i < siz + 1; i += 1 ){                                     
f[i] = strtof(end, &end);                                          
}                                                                          
while( isspace(*end) ){                                                    
end += 1;                                                          
}                                                                          
if( *end == '' || strcmp(end, "0.00n") ){                               
errx(EXIT_FAILURE, "Invalid input on line %d", lc);                
}                                                                          
return f;                                                                  
}                                                                                  
             
int                                                                                
get_row_count(FILE *in, char **line, size_t *cap, const char *name)                
{                                                                                  
if( getline(line, cap, in) <= 0 ){                                         
if( feof(in) ){                                                    
errx(EXIT_FAILURE, "Empty input");                         
} else {                                                           
err(EXIT_FAILURE, "%s", name);                             
}                                                                  
}                                                                          
char *end;                                                                 
int rows = strtol(*line, &end, 10);                                        
if( rows <= 0 ){                                                           
errx(EXIT_FAILURE, "invalid row count: %d", rows);                 
}                                                                          
if( *end != 'n' ){                                                        
errx(EXIT_FAILURE, "unexpected input on line 1");                  
}                                                                          
return rows;                                                               
}  
             
FILE *                                                                             
xfopen(const char *path, const char *mode)                                         
{                                                                                  
FILE *fp = path[0] != '-' || path[1] != '' ? fopen(path, mode) :         
*mode == 'r' ? stdin : stdout;                                     
if( fp == NULL ){                                                          
perror(path);                                                      
exit(EXIT_FAILURE);                                                
}                                                                          
return fp;                                                                 
}                                                                                  
             
void *                                                                             
xmalloc(size_t s)                                                                  
{                                                                                  
void *rv = malloc(s);                                                      
if( rv == NULL ){                                                          
perror("malloc");                                                  
exit(EXIT_FAILURE);                                                
}                                                                          
return rv;                                                                 
} 

最新更新