假设我们有一个字符串str
:
String str = "1,2,3,4444444444;5,6,7,8888888888;.9,10,11,1212121212;.";
定义字符串中嵌入的三个维度d1
,d2
和d3
,如下所示:
d1
包含以点“。”d2
包含以分号“;”d3
包含以逗号“,” d3
是d2
的孩子,d2
是d1
(父母)的孩子。 d1 > d2 > d3
。
我们希望能够访问字符串中嵌入的每个元素,这意味着我们应该有一个结果 - 如下所示的数组:
d[0][0][0] = "1";
d[0][0][1] = "2";
d[0][0][2] = "3";
d[0][0][3] = "4444444444";
d[0][1][0] = "5";
d[0][1][1] = "6";
d[0][1][2] = "7";
d[0][1][3] = "8888888888";
d[1][0][0] = "9";
d[1][0][1] = "10";
d[1][0][2] = "11";
d[1][0][3] = "12121212";
d[i][j][k]
其中k = [0, 2]
是整数。d[i][j][k]
其中k = 3
为长整数。我们希望现在将这些字符串转换为适当的整数类型(常规整数或长整数)。这意味着我们的最终数组应如下所示:
d[0][0][0] = 1; // int
d[0][0][1] = 2; // int
d[0][0][2] = 3; // int
d[0][0][3] = 4444444444; // long int
d[0][1][0] = 5; // int
d[0][1][1] = 6; // int
d[0][1][2] = 7; // int
d[0][1][3] = 8888888888; // long int
d[1][0][0] = 9; // int
d[1][0][1] = 10; // int
d[1][0][2] = 11; // int
d[1][0][3] = 12121212; // long int
这个想法是在一个基于c / c ++的arduino微控制器上实现的。
这是我对它的看法,不幸的是不能正常工作。
String data = "1,2,3,1445303228;4,5,6,1445303228;.7,8,9,1445303273;.";
int data_length = data.length() + 1;
if (data_length != 1) {
char d0[data_length]; // couldn't do it with String, let's try char
data.toCharArray(d0, data_length);
int size1 = 32, size2 = 64; // intuitive sizes
char d1[size1][136]; // strlen("1,2,3,1445303228") * 8, 17 * 8 = 136
int i = 0;
for (char *p = strtok(d0, "."); p != NULL; p = strtok(NULL, "."))
strcpy(d1[i++], p); // d1
int d1_length = i;
char d2[d1_length][size2][17]; // strlen("1,2,3,1445303228") = 16
int d2_length[size2];
for (int i = 0; i < size2; i++) d2_length[i] = 0; // initialize array = 0
for (int i = 0; i < d1_length; i++) {
int j = 0;
for (char *p = strtok(d1[i], ";"); p != NULL; p = strtok(NULL, ";"))
strcpy(d2[i][j++], p); // d2
d2_length[i] = j;
}
int d2_length_max = 0;
for (int i = 0; i < size2; i++)
if (d2_length[i] > d2_length_max) d2_length_max = d2_length[i];
char d3[d1_length][d2_length_max][4][10];
// d2 can have 4 d3's max, d3 can have 10 chars max
for (int i = 0; i < d1_length; i++) {
for (int j = 0; j < d2_length[i]; j++) {
int k = 0;
for (char *p = strtok(d2[i][j], ","); p != NULL; p = strtok(NULL, ","))
strcpy(d3[i][j][k++], p); // d3
}
}
int rows[d1_length][d2_length_max][3];
long rows_long[d1_length][d2_length_max];
for (int i = 0; i < d1_length; i++)
for (int j = 0; j < d2_length[i]; j++)
for (int k = 0; k < 3; k++)
rows[i][j][k] = atoi(d3[i][j][k]); // char array to integer
for (int i = 0; i < d1_length; i++)
for (int j = 0; j < d2_length[i]; j++) {
char temp[10];
for (int k = 0; k < 10; k++) temp[k] = d3[i][j][3][k];
rows_long[i][j] = atol(temp); // char array to long
}
}
请注意,长整数实际上是一个unix时间戳。
答案 0 :(得分:1)
使用纯C中的动态平面数组,然后分配3D数组 每次需要时,数组大小为两倍 您可以使用define:
设置第一个大小#define DEFAULT_SIZE 8
如我的评论中所述,格式很奇怪;.
应为.
,最终;.
应删除
我添加测试以检查下一行是否与第一行相同。
int main(void) {
char *data = "1,2,3,1445303228;4,5,6,1445303228;.7,8,9,1445303273;.";
char *p;
int size = DEFAULT_SIZE;
int nb_element = 0;
int s1 = 0;
int s2 = 0;
int cur1 = 0;
int cur2 = 0;
int cur3 = 0;
int *d = malloc(sizeof(int) * DEFAULT_SIZE);
int ***d3;
if (!d) {
return -1;
}
p = data;
while (*p) {
if (nb_element == size) {
size *= 2;
d = realloc(d, size * sizeof(int));
if (!d) {
return -1;
}
}
d[nb_element++] = strtol(p, &p, 10);
switch (*p) {
case ',':
cur1++;
if (s1 && cur1 > s1) {
fprintf(stderr, "Too many element for %d, %d:"
" get %d, expect %d\n", cur2, cur3, cur1, s1);
return -1;
}
break;
case ';':
cur1++;
cur2++;
if (s1 == 0) {
s1 = cur1;
}
cur1 = 0;
if (s2 && cur2 > s2) {
fprintf(stderr, "Too many element for %d:"
" get %d, expect %d\n", cur3, cur2, s2);
return -1;
}
break;
case '.':
dot:
cur2++;
cur3++;
if (s2 == 0) {
s2 = cur2;
}
cur2 = 0;
cur1 = 0;
break;
}
p++;
/* XXX: ack due to strange format */
if (*p == '.')
goto dot;
}
/*XXX! remove empty final line */
cur3--;
d3 = malloc(sizeof(int **) * cur3);
for (int i = 0; i < cur3; i++) {
d3[i] = malloc(sizeof(int *) * s2);
for (int j = 0; j < s2; j++) {
d3[i][j] = malloc(sizeof(int) * s1);
for (int k = 0; k < s1; k++) {
d3[i][j][k] = d[i * s2 + j * s1 + k];
}
}
}
free(d);
for (int i = 0; i < cur3; i++) {
for (int j = 0; j < s2; j++) {
for (int k = 0; k < s1; k++) {
fprintf(stdout, "d[%d][%d][%d] = %d\n", i,j,k, d3[i][j][k]);
}
}
}
return 0;
}
输出:
d[0][0][0] = 1
d[0][0][1] = 2
d[0][0][2] = 3
d[0][0][3] = 1445303228
d[0][1][0] = 4
d[0][1][1] = 5
d[0][1][2] = 6
d[0][1][3] = 1445303228
d[0][2][0] = 7
d[0][2][1] = 8
d[0][2][2] = 9
d[0][2][3] = 1445303273
答案 1 :(得分:0)
#include <stdio.h>
#include <stdlib.h>
int c1,c2,c3;
int n=0;
char sResult[20];
void PrintLevel(int lvl){
if(n){
printf("d[%d][%d][%d] = \"%s\"\n",c3,c2,c1,sResult);
n=0;
}
switch(lvl){
case 3:
c3++;
c2=c1=0;
break;
case 2:
c2++;
c1=0;
break;
case 1:
c1++;
}
return ;
}
void addChar(char c){
sResult[n]=c;
n++;
sResult[n]=c=0;
}
/*______________________________________________________________________
*/
int main(){
char buff[]= "0,1,2,4444444444;5,6,7,8888888888;.9,10,11,12121212;.";
PrintLevel(0);
char *p=buff;
char c;
int ret;
int lvl;
while(c=*p){
lvl=(c==',')?1:((c==';')?2:((c=='.')?3:0) );
if(lvl)
PrintLevel(lvl);
else
addChar(c);
p++;
}
PrintLevel(lvl);
}
答案 2 :(得分:0)
首先请注意,long
太小而无法容纳:4444444444
It's max size is: 2147483647
如果使用long long
,则可以通过regex_token_iterator
雄辩地解析字符串。解析函数应该接受输入string
和分隔符并返回分隔的strings
。这些输入允许在类似于以下的函数中重用:
auto parse(const string& input, const string& delimiter) {
const regex re("([^" + delimiter + "]+)" + delimiter + '?');
return vector<string>(sregex_token_iterator(input.begin(), input.end(), re, 1), sregex_token_iterator());
}
这将返回分区input
中的vector<string>
。然后可以对此返回进行分区,直到每个分区仅包含数字字符的第三维。此时stoll
可用于将string
转换为long long
。这种分区可以在嵌套循环中完成,如下所示:
vector<vector<vector<long long>>> foo;
for (auto& i : parse(str, "\\.")) {
foo.resize(foo.size() + 1);
for (auto& j : parse(i, ";")) {
foo.back().resize(foo.back().size() + 1);
for (auto& k : parse(j, ",")) {
foo.back().back().push_back(stoll(k));
}
}
}
这方面的一个关键方面是每个分区必须包含一个数字。这由'+'
中的re
强制执行,如果连续分隔符出现则不匹配。 stoll
非常健壮并且如果在输入string
中会占用空格,但是如果仅包含空格的string
或通常不包含数字的stoll
被输入它,它将抛出一个空格错误。如果这是一个问题,请务必在致电Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: dlopen(/Users/me/sx_direct_env/lib/python2.7/site-packages/cx_Oracle.so, 2): Library not loaded: /b/227/rdbms/lib/libclntsh.dylib.10.1
Referenced from: /Users/me/sx_direct_env/lib/python2.7/site-packages/cx_Oracle.so
Reason: image not found
之前检查您的输入。
您可以在此处查看此实例:http://ideone.com/4vjdBx
答案 3 :(得分:0)
使用主要基于@milevyo's answer的代码。
struct ds { int a = 0, b = 0, c = 0; long d = 0; };
struct data {
struct ds array[32][8];
int i, j[24];
int n = 0, d1, d2, d3; char r[11];
void get(String array) {
if (array.length() + 1 != 1) {
char buff[array.length() + 1];
array.toCharArray(buff, array.length() + 1);
char c; char *p = buff; int l;
while (c = *p) {
l = (c == ',') ? 1 : ((c == ';') ? 2 : ((c == '.') ? 3 : 0));
if (l) a(l); else ch(c); p++;
}
a(l);
}
}
void a(int l) {
if (n) {
if (d1 == 0) array[d3][d2].a = atoi(r);
else if (d1 == 1) array[d3][d2].b = atoi(r);
else if (d1 == 2) array[d3][d2].c = atoi(r);
else if (d1 == 3) array[d3][d2].d = atol(r);
i = d3 + 1; j[d3] = d2 + 1; n = 0;
}
switch (l) {
case 3: d3++; d2 = d1 = 0; break;
case 2: d2++; d1 = 0; break;
case 1: d1++; break;
}
}
void ch(char c) { r[n] = c; n++; r[n] = c = 0; }
} data;
void setup () {
Serial.begin(19200);
Serial.println("..");
data.get("1,2,3,1445433855;4,5,6,1445433855;.7,8,9,1445438763;.");
for (int i = 0; i < data.i; i++) {
for (int j = 0; j < data.j[i]; j++) {
for (int k = 0; k < 4; k++) {
if (k == 0) Serial.print(data.array[i][j].a);
else if (k == 1) Serial.print(data.array[i][j].b);
else if (k == 2) Serial.print(data.array[i][j].c);
else if (k == 3) Serial.print(data.array[i][j].d);
Serial.print("\t");
}
Serial.println();
}
Serial.println();
}
}
void loop () { }
这
1,2,3,1445433855;4,5,6,1445433855;.7,8,9,1445438763;.
到
..
1 2 3 1445433855
4 5 6 1445433855
7 8 9 1445438763
经由
..
data.array[0][0].a data.array[0][0].b data.array[0][0].c data.array[0][0].d
data.array[0][1].a data.array[0][1].b data.array[0][1].c data.array[0][1].d
data.array[1][0].a data.array[1][0].b data.array[1][0].c data.array[1][0].d
答案 4 :(得分:0)
我希望你保存了最后一篇文章,这是对最后一篇文章的更新,它按照要求处理2D数组。希望你发现它有用,如果是这样给我发一张明信片:)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/*__________________________________________________________________________
*/
struct DATA{
char a;
char b;
char c;
unsigned long d;
};
/*__________________________________________________________________________
allocate DATA struct, and fill it.
on error or no data, returns NULL
*/
struct DATA *ParseString(char **pstr){
int val=0;
char *p;
struct DATA *data;
if(!pstr) return NULL;
char *str=*pstr;
if(!str) return NULL;
// can be ommited
// skipping non digital chars
while(*str && !isdigit(*str))
str++;
//no digits?
if(!*str) return NULL;
p=str;
//ok at least one
data=(struct DATA*) calloc(1,sizeof(struct DATA));//calloc to initialize all to 0
for(int n=0;n<4;n++){
val=0;
while(isdigit(*p)){
val*=10;
val+=(*p)-'0';
p++;
}
switch(n){
case 0:
data->a=val;
break;
case 1:
data->b=val;
break;
case 2:
data->c=val;
break;
case 3:
data->d=val;
break;
}
val=0;
if(*p!=',')
break;
p++;
}
*pstr=p;
return data;
}
/*__________________________________________________________________________
calculate the size of DATA * arra[c1][c2]
*/
void countArrBoudaries(char *s,unsigned short *c1,unsigned short *c2){
*c1=*c2=0;
unsigned short _c1=0;
while(*s){
switch(*s){
case ';':
_c1++;
break;
case '.':
if(_c1>*c1)
*c1=_c1;
_c1=0;
*c2+=1;
break;
}
s++;
}
}
/*__________________________________________________________________________
*/
int main(void){
struct DATA **pdata,*data;
char buff[]="1,2,3,1445303228;4,5,6,1445303228;.7,8,9,1445303273;.";
char *p=buff;
unsigned short c1,c2;
countArrBoudaries(buff,&c1,&c2);
pdata=(struct DATA**)calloc((c2*c1),sizeof(pdata));
if(pdata){
// loading
for(int i=0;i<c1;i++)
for(int j=0;j<c2;j++)
pdata[i+(j*c1)]=ParseString(&p);
// printing:
for(int i=0;i<c1;i++)
for(int j=0;j<c2;j++){
data=pdata[i+(j*c1)];
if(data){
printf("data[%u][%u]={%d,%d,%d,%u};\n",i,j,data->a,data->b,data->c,data->d);
}else{
printf("data[%u][%u]=NULL;\n",i,j);
}
}
// freeing memory:
for(int i=0;i<(c1*c2);i++)
free(pdata[i]);
free(pdata);
}
printf("\n\nDONE\n\n");
return 0;
}