下面的代码试图解析包含这3行的文件:
0 2 5 9 10 12
0 1 0 2 4 1 2 3 4 2 1 4
2 3 3 -1 4 4 -3 1 2 2 6 1
并将它们存储在这些数组中:
int Line1[] = { 0, 2, 5, 9, 10, 12 };
int Line2[] = { 0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4 };
double Line3[] = { 2, 3, 3, -1, 4, 4, -3, 1, 2, 2, 6, 1 };
但实际上,实际输入文件中的字段数 未修复。 因此,每条线可以大于6,12和12。
我是否可以为此目的概括define
和sscanf
?
这是完整的代码:
#include <stdio.h>
#include <stdlib.h>
// This is hard coded
#define LINE1_COUNT 6
#define LINE2_COUNT 12
#define LINE3_COUNT 12
int main() {
int Line1[LINE1_COUNT], Line2[LINE2_COUNT] ;
float Line3[LINE1_COUNT] ;
int j, check;
FILE *file = fopen("test.dat","r");
if (file) {
char line[BUFSIZ];
if (fgets(line, BUFSIZ, file)) { // read line 1, integers
int *i = Line1;//for easier reading
check = sscanf(line, "%i%i%i%i%i%i", &i[0],&i[1],&i[2],&i[3],&i[4],&i[5]) ;
if (check != LINE1_COUNT){
fprintf(stderr, "Failed to read expected %d values from line 1\n", LINE1_COUNT);
exit(1);
}
}else fprintf(stderr, "Couldn't read line 1!\n");
if (fgets(line, BUFSIZ, file)) { // read line 2, integers
int *i = Line2;//for easier reading
check = sscanf(line, "%i%i%i%i%i%i%i%i%i%i%i%i",
&i[0],&i[1],&i[2],&i[3],&i[4],&i[5],&i[6],&i[7],&i[8],&i[9],&i[10],&i[11]) ;
if (check != LINE2_COUNT){
fprintf(stderr, "Failed to read expected %d values from line 2\n", LINE2_COUNT);
exit(1);
}
}else fprintf(stderr, "Couldn't read line 2!\n");
if (fgets(line, BUFSIZ, file)) { // read line 3, floats
float *f = Line3;//for easier reading
check = sscanf(line, "%f%f%f%f%f%f%f%f%f%f%f%f",
&f[0],&f[1],&f[2],&f[3],&f[4],&f[5],&f[6],&f[7],&f[8],&f[9],&f[10],&f[11]) ;
if (check != LINE3_COUNT){
fprintf(stderr, "Failed to read expected %d values from line 3\n", LINE3_COUNT);
exit(1);
}
}else fprintf(stderr, "Couldn't read line 3!\n");
fclose(file);
}else {
perror("test.dat");
}
for (j=0;j<LINE1_COUNT;j++){
printf("%i\t",Line1[j]);
}
printf("\n");
for (j=0;j<LINE2_COUNT;j++){
printf("%i\t",Line2[j]);
}
printf("\n");
for (j=0;j<LINE3_COUNT;j++){
printf("%f\t",Line3[j]);
}
printf("\n");
printf("Press return to exit");
getchar();
return 0;
}
答案 0 :(得分:2)
如果一行中的元素数量不固定(也可能是行数),您可以执行以下操作之一:
int line_elements[MAX_LINES][MAX_LINE_LENGTH]
- 但这仍然只有静态大小int* lines[]
,然后在迭代线条时动态分配所需的空间。您无法使用预定义数量为sscanf
的{{1}}。尝试使用strtok将字符串标记为标记,因为您将数字用空格分隔。
答案 1 :(得分:1)
好吧,这似乎做了你要求的,但它不使用泛型(如果我没有弄错的话是c ++特性)或泛化#define(我认为这是不可能的)。另外,我不确定效率:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
//dont (cant) hard-code sizes (see main())
int* parse_int_line(char* line, int* sz)
{
int* line_data;
int* tmp;
line_data = malloc(sizeof(int) * ((*sz)=1));
if(!line_data){return 0;}
while(1==sscanf(line,"%i",&(line_data[(*sz)-1])))
{
while(*(line++)==' '){ /*pass*/ }//chew through leading spaces
while(*(line++)!=' '){*line=' ';}//and the number we just got
tmp = realloc(line_data,sizeof(int) * (++(*sz)));
if(tmp){line_data = tmp;}
else{fprintf(stderr,"nonfatal memory allocation error\n");break;}
}
(*sz)--;
return line_data;
}
void print_int_line(int* line, int sz)
{
int i;
for(i=0;i<sz;i++)
{
printf(" %i",line[i]);
}
printf("\n");
}
float* parse_float_line(char* line, int* sz)
{
float* line_data;
float* tmp;
line_data = malloc(sizeof(float) * ((*sz)=1));
if(!line_data){return 0;}
while(1==sscanf(line,"%f",&(line_data[(*sz)-1])))
{
while(*(line++)==' '){ /*pass*/ }//chew through leading spaces
while(*(line++)!=' '){*line=' ';}//and the number we just got
tmp = realloc(line_data,sizeof(float) * (++(*sz)));
if(tmp){line_data = tmp;}
else{fprintf(stderr,"nonfatal memory allocation error\n");break;}
}
(*sz)--;
return line_data;
}
void print_float_line(float* line, int sz)
{
int i;
for(i=0;i<sz;i++)
{
printf(" %.2f",line[i]);
}
printf("\n");
}
int main(int argc, char** argv)
{
int sz1=0,sz2=0,sz3=0;
int* line1 = 0;
int* line2 = 0;
float* line3 = 0;
FILE* file = 0;
file = fopen("C:/DevCpp/Projects/junk/test.txt","r");
if(file)
{
char line[BUFSIZ];
if(fgets(line,BUFSIZ,file))
{
line1 = parse_int_line(line,&sz1);
print_int_line(line1,sz1);
}
else{fprintf(stderr,"line read error\n");}
if(fgets(line,BUFSIZ,file))
{
line2 = parse_int_line(line,&sz2);
print_int_line(line2,sz2);
}
else{fprintf(stderr,"line read error\n");}
if(fgets(line,BUFSIZ,file))
{
line3 = parse_float_line(line,&sz3);
print_float_line(line3,sz3);
}
else{fprintf(stderr,"line read error\n");}
}
else
{
fprintf(stderr,"could not open \"test.txt\"\n");
}
if(line1){free(line1);}
if(line2){free(line2);}
if(line3){free(line3);}
printf("Press return to exit");
getchar();
return 0;
}
顺便说一下,请评论一下这项工作是否适合你。
答案 2 :(得分:0)
我建议使用stl容器类向量&lt;&gt;或为此目的动态分配的数组。
答案 3 :(得分:0)
这看起来与this question的问题相同。由于字段数是可变的,因此sscanf无法完成工作。它需要固定数量的字段。并且#defines绝对不能在运行时参数化。 strtok()绝对是要走的路。有关更多详细信息和问题,请参阅其他问题的答案。