作为程序的一部分,此函数接收一个指向字符串的指针,并检查它是否是
markdown
表的有效行,可以提取其中的数据。
如果它识别出表头、表头和表体之间的
.md
语法分隔或空行,则可能返回 false,否则返回 true。
示例:
| Lebensmittel/Gericht | Gewicht in gr | kcal | ->false
| -------------------- | ------------- | ---- | ->false
| Wildkräutersalat | 42 | 8 | ->true
| Rucola | 40 | 10 | ->true
| | | | ->false
| Brot | 73 | 161 | ->true
这是我到目前为止的方法:
bool check_line(char* line) {
puts(line); // console output for debugging
if(strcmp(line,"| Lebensmittel/Gericht | Gewicht in gr | kcal |") != 0) { // check for specific header
return false;
}
if(line[0] == '|' //check for underline under header
&& line[1] == ' '
&& line[2] == '-'
&& line[3] == '-'
&& line[4] == '-'
) {
return false;
}
// check for empty table rows
char* start;
char* end;
if(start = strstr(line,'|')){
start++;
if(end = strstr(start,'|')){
for(size_t i; line[i] != '|'; i++ ){ //Iterate between the two '|' if the string is blank-space
if( line[i] != ' ');
return true; //return true if there are chars between two '|'
}
return false; //return false if the string between the two '|' contains ony blank-space
}
}
return false;
}
我已经使用这种方法来检查“|”之间是否有空行字符。 但它无法正常工作。
通过更改代码以使用定界符“|”分割 char*,您可以检查该行的第二个和第三个元素是否仅由数字组成以及是否只有 3 个元素。如果是这样,则该行有效:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
static char ** strsplit(const char *s, const char *delim) {
void *data;
char *_s = (char *)s;
const char **ptrs;
size_t ptrsSize, nbWords = 1, sLen = strlen(s), delimLen = strlen(delim);
while ((_s = strstr(_s, delim))) {
_s += delimLen;
++nbWords;
}
ptrsSize = (nbWords + 1) * sizeof(char *);
ptrs = data = malloc(ptrsSize + sLen + 1);
if (data) {
*ptrs = _s = strcpy(((char *)data) + ptrsSize, s);
if (nbWords > 1) {
while ((_s = strstr(_s, delim))) {
*_s = '\0';
_s += delimLen;
*++ptrs = _s;
}
}
*++ptrs = NULL;
}
return data;
}
static char *trim_left(char *str) {
int len = strlen(str);
char *cur = str;
while (*cur && isspace(*cur)) {
++cur;
--len;
}
if (str != cur) memmove(str, cur, len + 1);
return str;
}
static char *trim_right(char *str) {
int len = strlen(str);
char *cur = str + len - 1;
while (cur != str && isspace(*cur)) --cur;
cur[isspace(*cur) ? 0 : 1] = '\0';
return str;
}
static char *trim(char *str) {
trim_right(trim_left(str));
return str;
}
static bool is_valid_number(const char *str) {
bool is_valid = true;
for (int i = 0; str[i + 1] != '\0' && is_valid; i++) {
is_valid = '0' <= str[i] && str[i] <= '9';
}
return is_valid;
}
bool check_line(const char *line) {
const char *delim = "|";
char **parts = strsplit(line, delim);
int element_count = 0;
bool is_valid = true;
for (int i = 1; parts[i + 1] != NULL && is_valid; i++) {
char *trimmed_part = trim(parts[i]);
if (i == 1) {
is_valid = !is_valid_number(parts[i]);
} else if (i == 2 || i == 3) {
is_valid = is_valid_number(parts[i]);
}
element_count++;
}
return is_valid && element_count == 3;
}
int main() {
const char *data[] = {
"| Lebensmittel/Gericht | Gewicht in gr | kcal |", // false
"| -------------------- | ------------- | ---- |", // false
"| Wildkräutersalat | 42 | 8 |", // true
"| Rucola | 40 | 10 |", // true
"| | | |", // false
"| Brot | 73 | 161 |" // true
};
int size = sizeof(data) / sizeof(data[0]);
for (int i = 0; i < size; i++) {
bool is_valid_line = check_line(data[i]);
printf("%s -> %s\n", data[i], is_valid_line ? "True" : "False");
}
return 0;
}