Parsing doubles from char into a 2D array with sscanf
对于C初学者来说是典型的,我在理解数组,数组指针和数组指针时遇到一些问题。不幸的是,这里提供的信息对我没有太大帮助,因为所有这些信息都处理"更轻松"的问题。这是我的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* random.c */ #include <stdio.h> #include <time.h> #include <stdlib.h> int main(){ double particles[4][22]; int seed,i,x,y; double px_buf, py_buf, pz_buf; seed=time(NULL); srand(seed); /* The random numbers are generated between 1E-12 and 10E-12 */ /*Double precision floats support up to 15 decimal places*/ for(i=0;i<20;i++){ px_buf=((double)rand()/RAND_MAX)*9001E-15; py_buf=((double)rand()/RAND_MAX)*9001E-15; pz_buf=((double)rand()/RAND_MAX)*9001E-15; particles[0][i]=px_buf; particles[1][i]=py_buf; particles[2][i]=pz_buf; printf("(step: %i) The following noise momentum was generated: (%.15E,%.15E,%.15E)\ ",i,px_buf,py_buf,pz_buf); } sscanf("p[20] = nullvector(45.0000000000106,33.03951484238976,14.97124733712793,26.6317895033428)", \\ "p[20] = nullvector(%lf,%lf,%lf,%lf)",&particles[3][20],&particles[0][20],&particles[1][20],&particles[2][20]); for(y=0;y<22;y++){ for(x=0;x<3;x++){ printf("%.15E \\t", particles[x][y]); } printf("\ "); } return 0; } |
此代码可以正常工作,但是如您所见,最后四个(y = 21)数组条目为"空",我想以与现在使用sscanf行相同的方式填充它。
我想用合适的解析器函数替换sscanf部分,但是我完全困惑如何正确地传递指针,尤其是如何使用address-of(
因为您事先知道了表示粒子的向量的大小,所以反转数组索引更有意义:
1 2 3 | #define NUM_PARTICLES 22 /* ... */ double particles[NUM_PARTICLES][4]; |
然后将您的解析功能更改为更易于编写:
1 2 3 4 5 6 7 8 | void parser(char *input, double particles[][4]){ sscanf( input, "p[20] = nullvector(%lf,%lf,%lf,%lf)", &particles[20][3], &particles[20][0], &particles[20][1], &particles[20][2] ); } |
这将编译并执行您想要的操作。另外,解析器不需要知道字段中有多少粒子。相反,它只需要知道粒子是如何表示的(应该如此)。
解析器需要知道字段中有多少个粒子,这是一个很大的代码,这说明出了点问题。更改程序使其更有意义,它也可以解决您的错误!
作为提示,请考虑这样的二维数组:
1 | double arr[rows][columns]; |
新文件将在具有GCC 4.6的Linux上编译而不会出现错误。
澄清度
why do we need to give the number of columns to the parser function?
因为否则该函数将没有足够的信息来计算给定值的偏移量。
一维数组看起来像这样:
1 | |value0|value1|value2|... |
通过告诉编译器这是一个
因此,当您访问此阵列时,说
1 | address of value (bytes) = 17 * width of double (bytes) |
现在考虑多维数组
1 | |va0|vb0|va1|vb1|va2|vb2|... |
当您尝试访问一个值(例如
1 | address of value (bytes) = (3 * width of inner array) + (1 * size of element) |
其中
1 | width of inner array = no of elements * size of elements. |
在上面的例子中,内部数组的元素数为2,其大小为双精度数。
因此,它需要内部数组的宽度("列")才能找到该值的真实地址,否则在索引时无法计算偏移量。
这是因为C使用行优先顺序。