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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C将“字符串”的2D数组收集到数组中,然后将每个2D传递到C98函数中相关的知识,希望对你有一定的参考价值。

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

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

我遇到的问题是创建一个全面的测试人员,我希望通过相同的API运行许多场景,内容略有不同。在Java,javascript,COBOL,Ruby,Python,Assembler等中......它就像数组中的“简单”一样......在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 *。使用该问题的建议会产生无法编译的代码,因为无法将“表格列表”/ 3d数组中的结果转换为可以传递给API的可用类型。

答案

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

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:

我希望它有所帮助。

以上是关于C将“字符串”的2D数组收集到数组中,然后将每个2D传递到C98函数中的主要内容,如果未能解决你的问题,请参考以下文章

找到2D数组中的最大值

将 char 2d 数组转换为 2d char 数组列表时出现问题

c#如何将2D数组拆分为较小的2D数组(块)列表?

C语言中,如何将一个数组中的数值转换成字符串输出?

如何在多维数组/网格c ++中创建List

如何返回图中2个节点之间所有可能路径的2D数组? (C ++)