C 是否有一种方法可以检查空终止字节后的字符串内容?
我希望通过管道将输入传输到我的程序,该程序只接受对正则表达式有效的行,即最大长度为3的数字,后跟至少一个空格字符,后跟最大长度为7的负数或正数 下面的电话C 是否有一种方法可以检查空终止字节后的字符串内容?,c,string,C,String,我希望通过管道将输入传输到我的程序,该程序只接受对正则表达式有效的行,即最大长度为3的数字,后跟至少一个空格字符,后跟最大长度为7的负数或正数 下面的电话 echo -e '1 1\n1 1\x00junk' | ./myProgram 通过我的正则表达式,但不应该。 我想它之所以产生getline(),是因为我的正则表达式只获取空终止字节前面的内容,而忽略后面的所有内容 有没有一种方法可以在不破坏字符串分配内存访问的情况下检查空终止字节后的内容,从而使给定调用以错误结束 #define _G
echo -e '1 1\n1 1\x00junk' | ./myProgram
通过我的正则表达式,但不应该。
我想它之所以产生getline()
,是因为我的正则表达式只获取空终止字节前面的内容,而忽略后面的所有内容
有没有一种方法可以在不破坏字符串分配内存访问的情况下检查空终止字节后的内容,从而使给定调用以错误结束
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
#include <errno.h>
int main() {
int reg;
regex_t regex;
char *regexStr = "^[0-9]{1,3} +-?[0-9]{1,7}(\n|\r|\r\n|0a|0d0a)?$";
int size = 16;
char *buffer = malloc(size * sizeof(char));
size_t len = size;
ssize_t nread;
if (regcomp(®ex, regexStr, REG_EXTENDED)) {
fprintf(stderr, "Couldn't compile regular expression.\n");
return -1;
}
while ((nread = getline(&buffer, &len, stdin)) != EOF) {
if (errno == ENOMEM) { // error if getline() couldnt allocate buffer
fprintf(stderr, "Couldn't allocate enough memory.\n");
return -1;
}
reg = regexec(®ex, buffer, 0, NULL, 0);
if (reg == REG_NOMATCH) { //input invalid if regular expression doesnt match with line
fprintf(stderr, "Input invalid.\n");
return -1;
}
printf("%s", buffer);
}
printf("\n");
printf("Input was valid.\n");
return 0;
}
定义GNU源
#包括
#包括
#包括
#包括
int main(){
int-reg;
regex_t regex;
char*regexStr=“^[0-9]{1,3}+-?[0-9]{1,7}(\n | \r | \r\n | 0a | 0d0a)?$”;
int size=16;
char*buffer=malloc(大小*sizeof(char));
尺寸长度=尺寸;
ssize_t nread;
if(regcomp(®ex,regexStr,regu扩展)){
fprintf(stderr,“无法编译正则表达式。\n”);
返回-1;
}
while((nread=getline(&buffer,&len,stdin))!=EOF){
如果(errno==ENOMEM){//getline()无法分配缓冲区时出错
fprintf(stderr,“无法分配足够的内存。\n”);
返回-1;
}
reg=regexec(®ex,buffer,0,NULL,0);
if(reg==reg_NOMATCH){//如果正则表达式与行不匹配,则输入无效
fprintf(stderr,“输入无效。\n”);
返回-1;
}
printf(“%s”,缓冲区);
}
printf(“\n”);
printf(“输入有效。\n”);
返回0;
}
来自:
使用REG\u STARTEND
。像这样:
regmatch_t match[1] = {0};
match[0].rm_so = 0;
match[0].rm_eo = nread;
reg = regexec(®ex, buffer, 0, match, REG_STARTEND);
结果:
$ echo -e '1 1\n1 1\x00junk' | ./a.out
1 1
Input invalid.
将空字节与
regexec
匹配是一件棘手的事情,但是可以在KamilCuk记录的带有可选标志REG_STARTEND
的某些体系结构上实现,但此功能是非标准的
POSIX系统有一个简单的解决方案:与fgets()
不同,getline()
返回从流中读取的字节数,因此您可以通过比较nread
与strlen(缓冲区)
来检测这些字节中是否有空字节
以下是经过修改的版本,以及一些其他修复:
定义GNU源
#包括
#包括
#包括
#包括
#包括
int main(){
int-reg;
regex_t regex;
const char*regexStr=“^[0-9]{1,3}+-?[0-9]{1,7}(\n | \r | \r\n)?$”;
char*buffer=NULL;//无需预先分配缓冲区
大小\u t大小=0;
ssize_t nread;
if(regcomp(®ex,regexStr,regu扩展)){
fprintf(stderr,“无法编译正则表达式。\n”);
返回-1;
}
对于(;;){
errno=0;//设置errno以便我们可以在getline之后测试它
nread=getline(&buffer,&size,stdin);
如果(nread<0){
if(errno==ENOMEM){
//如果getline()无法分配缓冲区,则出错
fprintf(stderr,“无法分配足够的内存。\n”);
返回-1;
}
打破
}
如果(strlen(缓冲区)!=(大小)nread){
fprintf(stderr,“无效输入:包含空字节\n”);
返回-1;
}
reg=regexec(®ex,buffer,0,NULL,0);
如果(reg==reg\U NOMATCH){
//如果正则表达式与行内容不匹配,则输入无效
fprintf(stderr,“输入无效。\n”);
返回-1;
}
printf(“%s”,缓冲区);
}
printf(“\n”);
printf(“输入有效。\n”);
返回0;
}
将输入视为二进制(使用fread
)。nread
具有缓冲区的长度。但是我看不到一种方法可以将长度传递给regexec
。(getline()!=EOF
EOF
不一定是-1,并且getline
错误时返回-1,因此我将!=-1
)是的,nread
告诉您行中的字符数。字符串终止空字节后没有字符串内容。这正是《终结者》的意义所在。当然,包含字符串的数组可以比字符串本身大,但查看结束符意味着将其视为普通数组,而不是字符串。期望在字符串上工作的函数不会这样做。
$ echo -e '1 1\n1 1\x00junk' | ./a.out
1 1
Input invalid.