The reason why I would want to do this is because I want to read from a file line-by-line, and for each line check whether it matches a regex. I am using the getline() function, which puts the line into a char *
type variable. I am trying to use regexec()
to check for a regex match, but this function wants you to provide the string to match as a const char *
.
So my question is, can I create a const char *
from a char *
? Or perhaps is there a better way to approach the problem I'm trying to solve here?
EDIT: I was requested to provide an example, which I didn't think about and apologise for not giving one in the first place. I did read the answer by @chqrlie before writing this. The following code gives a segmentation fault.
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
#include <regex.h>
int main() {
FILE * file = fopen("myfile", "r");
char * line = NULL;
size_t len = 0;
ssize_t read;
regex_t regex;
const char * regexStr = "a+b*";
if (regcomp(®ex, regexStr, 0)) {
fprintf(stderr, "Could not compile regex \"%s\"\n", regexStr);
exit(1);
}
while ((read = getline(&line, &len, file)) != -1) {
int match = regexec(®ex, line, 0, NULL, 0);
if (match == 0) {
printf("%s matches\n", line);
}
}
fclose(file);
return 0;
}
char *
can be converted to const char *
without any special syntax. The const
in this type means that the data pointed by the pointer will no be modified via this pointer.
char array[] = "abcd"; // modifiable array of 5 bytes
char *p = array; // array can be modified via p
const char *q = p; // array cannot be modified via q
Here are some examples:
int strcmp(const char *s1, const char *s2);
size_t strlen(const char *s);
char *strcpy(char *dest, const char *src);
As you can see, strcmp
does not modify the strings it receives pointers to, but you can of course pass regular char *
pointers to it.
Similarly, strlen
does not modify the string, and strcpy
modifies the destination string but not the source string.
EDIT: You problem has nothing to do with constness conversion:
You do not check the return value of fopen()
, the program produces a segmentation fault on my system because myfile
does not exist.
You must pass REG_EXTENDED
to compile a regex with the newer syntax such asa+b*
Here is a corrected version:
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>
int main() {
FILE *file = fopen("myfile", "r");
char *line = NULL;
size_t len = 0;
ssize_t read;
regex_t regex;
const char *regexStr = "a+b*";
if (file == NULL) {
printf("cannot open myfile, using stdin\n");
file = stdin;
}
if (regcomp(®ex, regexStr, REG_EXTENDED)) {
fprintf(stderr, "Could not compile regex \"%s\"\n", regexStr);
exit(1);
}
while ((read = getline(&line, &len, file)) != -1) {
int match = regexec(®ex, line, 0, NULL, 0);
if (match == 0) {
printf("%s matches\n", line);
}
}
fclose(file);
return 0;
}