C将“字符串”的2D数组收集到数组中,然后将每个2D传递给C98函数

时间:2018-03-01 19:13:14

标签: c arrays multidimensional-array

我遇到了一些C语法的问题,我希望有人知道答案,或者知道一篇解释我可以从中学到的紧密解决方案的文章。我知道如何用十几种其他语言(包括多个汇编程序)执行此操作,但我无法弄清楚C语法(不是C ++,或者C99 +必须是C98,因为有5个操作系统支持)才能做到这一点。

我有一个库API,它接受一个二维数组的“字符串”N x 2(N行,2列),带有一个行数的整数。这个数组几乎总是被定义为调用应用程序代码中的常量,因为在该应用程序的编译时几乎总是知道该信息。我有代码工作,接受数组并正确处理它,所以API实际上工作正常。目的是避免在调用应用程序的新版本发布之前永远不会改变的内存分配/释放(即我通过允许它们使用编译时常量来帮助应用程序开发人员使用API​​)。 p>

我遇到的问题是创建一个全面的测试人员,我希望通过相同的API运行多个场景,内容略有不同。在Java,JavaScript,COBOL,Ruby,Python,汇编程序等中。它与数组的数组一样“简单”......在C语言中,并非如此。

我定义的工作API是:

CTS parse(const char* contents, size_t len, const char* app
            , const char* pVs[][2], const int pvLen);

这是我正在测试的恼人代码部分;这第一部分工作得很好并且正确地测试了代码,但是如果我想添加更多的变化,那么愚蠢的case语句将变得丑陋(呃)和蠢(这与我目前在C中的技能非常接近:D):

int i = 0, f = 0, lf = 0, len = 0;
int lengths[] = {1, 3, 1, 1, 1};
char* filt1[][2] = { {"CS","5"},{"AS","5.4"},{"OS","16.*"} };
char* filt2[][2] = { {"CS","6.2"} };
char* filt3[][2] = { {"CS","5.4"} };
char* filt4[][2] = { {"CS","*"} };
char* filt5[][2] = { {"",""} };

for(i = 1; i < 6; i++) {         // Filter cases (filt 1=5)
     lf = lengths[i];
     for(f = 0; f < 6; f++) {   // Input files to be checked
           printf("Test #%i:\n", f);
           file = loadFile(f);
           len = (file == NULL ? 0 : strlen(file));
           switch(i) {                     // WTF Code!! stupid way to do this!
           case 1:
                l = parse(file, len, NULL, filt1, lf);
                break;
           case 2:
                l = parse(file, len, NULL, filt2, lf);
                break;
           case 3:
                l = parse(file, len, NULL, filt3, lf);
                break;
           case 4:
                l = parse(file, len, NULL, filt4, lf);
                break;
           case 5:
                l = parse(file, len, NULL, filt5, lf);
                break;
           }
           // Finish testing "l" result
           ...
     }
}

我很想知道如何将上面的内容改写成这样的东西(我真的不关心NULL选项,我可以把它留在组测试之外):

?????? filters[6] = {NULL, filt1, filt2, filt3, filt4, filt5};

for(i = 1; i < 6; i++) {
     lf = lengths[i];
     for(f = 0; f < 6; f++) {
           char* filter[][2] = filters[i];       // What goes here?

           printf("Test #%i:\n", f);
           file = loadFile(f);
           len = (file == NULL ? 0 : strlen(file));

           l = parse(file, len, NULL, filter, lf);

           // Finish testing "l" result
     }
}

忽略NULL选项,如何构建(技术上)稀疏内容的三维数组(即并非所有“深度”行都是相同的维度)并将其传递给API函数?我已经在StackOverflow中挖掘了将近2天,没有任何例子可以使用char *或者我想要的接收API签名。

我已经检查了Error passing 2D char* array into a function,但它只引用了固定数组大小,只有2维。

不是How to pass 2D array (matrix) in a function in C?的副本,因为该问题涉及整数而不是“字符串”/ char *。使用该问题的建议会产生无法编译的代码,因为无法将“list of tables”/ 3d数组中的结果转换为可以传递给API的可用类型。

1 个答案:

答案 0 :(得分:0)

这是一个很好的问题。我希望有人能拿出好的答案。 对我而言,结构阵列的解决方案似乎更清晰,更简单。 如果

typedef struct sar{
    char* (*f)[2];
}SAR

然后你的循环简化为:

SAR ar[6];     
ar[0].f = NULL;
ar[1].f = filt1;   
ar[2].f = filt2; 
ar[3].f = filt3;  
ar[4].f = filt4; 
ar[5].f = filt5; 

for(i = 1; i < 6; i++) {
    lf = lengths[i];
    for(f = 0; f < 6; f++) {
       printf("Test #%i:\n", f);
       file = loadFile(f);
       len = (file == NULL ? 0 : strlen(file));
      l = parse(file, len, NULL, ar[i].f, lf);
       // Finish testing "l" result
    }
}

我没有为您的程序提供所有数据,但有一些简化 我验证了输出。

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

typedef struct sar{
    char* (*f)[2];
}SAR;

int parse(const char* contents, size_t len, const char* app
            ,char* pVs[][2], const int pvLen)
{

    for(int i=0; i < pvLen; i++)
        printf("%s %s   ", pVs[i][0], pVs[i][1]);       
    printf("\n");       
    return 1;                
}

char * loadFile(int f)
{
    return NULL;
}

int main(void) 
{            
    char * file;
    int l;

    int i = 0, f = 0, lf = 0, len = 0;

    int lengths[] = {1, 3, 1, 1, 1};

    char* filt1[][2] = { {"CS","5"},{"AS","5.4"},{"OS","16.*"} };
    char* filt2[][2] = { {"CS","6.2"} };
    char* filt3[][2] = { {"CS","5.4"} };
    char* filt4[][2] = { {"CS","*"} };
    char* filt5[][2] = { {"",""} };

    for(i = 1; i < 6; i++) {         // Filter cases (filt 1=5)
         lf = lengths[i];

        for(f = 0; f < 6; f++) {   // Input files to be checked

           printf("Test #%i:\n", f);
           file = loadFile(f);
           len = (file == NULL ? 0 : strlen(file));
           switch(i) {                     // WTF Code!! stupid way to do this!
           case 1:
                l = parse(file, len, NULL, filt1, lf);
                break;
           case 2:
                l = parse(file, len, NULL, filt2, lf);
                break;
           case 3:
                l = parse(file, len, NULL, filt3, lf);
                break;
           case 4:
                l = parse(file, len, NULL, filt4, lf);
                break;
           case 5:
                l = parse(file, len, NULL, filt5, lf);
                break;
           }
           // Finish testing "l" result
           //...
        }
    }

    printf("............\n");

    SAR ar[6];

    ar[0].f = NULL;
    ar[1].f = filt1;   
    ar[2].f = filt2; 
    ar[3].f = filt3;  
    ar[4].f = filt4; 
    ar[5].f = filt5; 

    for(i = 1; i < 6; i++) {
        lf = lengths[i];
        for(f = 0; f < 6; f++) {
           printf("Test #%i:\n", f);
           file = loadFile(f);
           len = (file == NULL ? 0 : strlen(file));
          l = parse(file, len, NULL, ar[i].f, lf);
           // Finish testing "l" result
        }
    }

    return 0
}

输出:

Test #0:
CS 5   AS 5.4   OS 16.*   
Test #1:
CS 5   AS 5.4   OS 16.*   
Test #2:
CS 5   AS 5.4   OS 16.*   
Test #3:
CS 5   AS 5.4   OS 16.*   
Test #4:
CS 5   AS 5.4   OS 16.*   
Test #5:
CS 5   AS 5.4   OS 16.*   
Test #0:
CS 6.2   
Test #1:
CS 6.2   
Test #2:
CS 6.2   
Test #3:
CS 6.2   
Test #4:
CS 6.2   
Test #5:
CS 6.2   
Test #0:
CS 5.4   
Test #1:
CS 5.4   
Test #2:
CS 5.4   
Test #3:
CS 5.4   
Test #4:
CS 5.4   
Test #5:
CS 5.4   
Test #0:
CS *   
Test #1:
CS *   
Test #2:
CS *   
Test #3:
CS *   
Test #4:
CS *   
Test #5:
CS *   
Test #0:

Test #1:

Test #2:

Test #3:

Test #4:

Test #5:

............
Test #0:
CS 5   AS 5.4   OS 16.*   
Test #1:
CS 5   AS 5.4   OS 16.*   
Test #2:
CS 5   AS 5.4   OS 16.*   
Test #3:
CS 5   AS 5.4   OS 16.*   
Test #4:
CS 5   AS 5.4   OS 16.*   
Test #5:
CS 5   AS 5.4   OS 16.*   
Test #0:
CS 6.2   
Test #1:
CS 6.2   
Test #2:
CS 6.2   
Test #3:
CS 6.2   
Test #4:
CS 6.2   
Test #5:
CS 6.2   
Test #0:
CS 5.4   
Test #1:
CS 5.4   
Test #2:
CS 5.4   
Test #3:
CS 5.4   
Test #4:
CS 5.4   
Test #5:
CS 5.4   
Test #0:
CS *   
Test #1:
CS *   
Test #2:
CS *   
Test #3:
CS *   
Test #4:
CS *   
Test #5:
CS *   
Test #0:

Test #1:

Test #2:

Test #3:

Test #4:

Test #5:

我希望它有所帮助。