2

我的问题有两个:

我正在使用 POSIX 正则表达式,并且为模式匹配设置了一个非常好的系统,并且正在工作,但是处理 C 对字符串操作的低级/难以使用的支持非常困难,尤其是在 sub 部门-字符串方法。我知道下面的例子不是一个小插曲,所以请多多包涵,但我觉得本节展示了我如何设置 POSIX 正则表达式以及我是如何使用它的。我的主要问题是,如何从 POSIX 中为每个模式匹配提取字符串并将其放入一个字符串/字符数组中,我可以安全地使用正常的 C 字符串函数,例如在此处找到的函数: http ://faculty.edcc.edu/ paul.bladek/c_string_functions.htm? 似乎我可以从模式匹配内部结构中获取字符串,但是每次我对模式匹配执行我认为正常的子字符串操作时,C 都会死掉。

下面的例子显示了以前工作过的代码,但是直到我决定将变量“result”从数组更改为 (char *) (你可以看到旧的方式被注释掉了)并尝试使用 C 的内存分配方法来做这个权利。您可以在输出中看到它有多远,变量“结果”出来是正确的,但是当我使用 strstr(...) 时,程序在 IF 比较时崩溃,原因我无法确定。

我的最后一个问题,NULL 终止 (char *) 的最佳方法是什么?显然,我在下面这样做的方式可能是一个问题。

代码:(注意,“storage”是一个大尺寸的字符数组,包含正在执行模式匹配的文本)

regex_t r;  // stores regex
regmatch_t m[50];  // stores parts of file-string that matched the regex
const char * p = storage; // pointer to string that will be read in by regexec(...)
char matches[tracker][BUFFSIZE]; // 2D array containing a collection of strings
int ind = 0;  // indexing variable "matches" array
printf("### Collecting Pattern Matches ###\n");
int regExErr1 = regcomp(&r, "<[^<>]+=[[:space:]]*\"[^\"]+\"", REG_EXTENDED|REG_NEWLINE);
if( regExErr1 ){ 
    fprintf(stderr, "Fail to compile regex!\n"); 
    exit(1); 
}
while(1){
    regExErr1 = regexec(&r, p, 10, m, 0);
    if( regExErr1 != 0 ){ 
        fprintf(stderr, "Done finding URL pattern matches...\n"); 
        break; 
    }   
    int i = 0;
    while(1){
        if(m[i].rm_so == -1){
            break;
        }
        printf("entering loop at index %i\n", i);
        int start = m[i].rm_so;
        int finish = m[i].rm_eo;
        //char result[(finish - start)];
        char * result = (char *) malloc(strcspn(strstr(p + start, "<"), ">"));
        //strcpy(result, strstr(("%.*s\n", (finish - start), p + start), "<"));
        strcpy(result,("%.*s\n", strcspn((p+ start), ">"), strstr(p + start, "<")));
        result[strcspn(result, ">")+1] = 0;
        printf("LOOKING AT:  %s\n", result);
        if(strstr(result, "href") != NULL || strstr(result, "HREF") != NULL || strstr(result, "src") != NULL){
            printf("## CONSIDERING:  %s\n", result);
            if(strstr(result, "http:") == NULL && strstr(result, "mailto") == NULL){
                printf("Pattern is a relative URL.\n");
                strcpy(result, strstr(result, "\"") + 1);
                result[strcspn(result, "\"")] = 0;
                strcpy(result, relativePathCondense(result, "."));
                strcpy(matches[ind], base);
                strcat(matches[ind], result);
                matches[ind][(strlen(base) + strlen(result))] = 0; // NULL terminate the string match in the collection
                printf("Stored %i ==  %s\n", ind, matches[ind]);
                ...
                ind++; // update the counter to the 2D record array "matches"
            }else if(strstr(result, "http:") != NULL || strstr(result, "mailto:") != NULL){
                printf("Pattern is an absolute URL.\n");
                strcpy(result, strstr(result, "\"") + 1);
                result[strcspn(result, "\"")] = 0;
                printf("Trimmed expression is %s\n", result);
                strcpy(matches[ind], result);
                matches[ind][strlen(result)] = 0; // NULL terminate the string match in the collection
                printf("Stored %i ==  %s\n", ind, matches[ind]);
                ...
                ind++;                  
            }
        }
        i++;
    }
    p += m[0].rm_eo; // this will move the pointer p to the end of last matched pattern and on to the start of a new one
}

输出:

### Collecting URL's from stored HTML source document! ###
entering loop at index 0
LOOKING AT:  <BODY BGCOLOR = "#FFFFF0">
Segmentation fault (core dumped)
4

1 回答 1

1
    strcpy(result,("%.*s\n", strcspn((p+ start), ">"), strstr(p + start, "<")));

这并不像你想的那样......表达式("%.*s\n", ...只是使用逗号运算符expr, expr,它计算两个表达式,但具有右手 expr 的值。我想你打算在sprintf这里使用。

(另外,如果不仔细计算,您可能会malloc少一个字节。通常的习惯用法是strlen(s) + 1,但我必须更深入地考虑您的strspn

于 2013-03-14T17:54:34.957 回答