Regex in C not working (And I can't find why) - c

Tested on regexpal.com this regex works fine, but when run in my program it doesn't work at all. The objective is to pull the video ID from the url (And throw an error if it's not a valid url)
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
regex_t expression;
char * regexpression = "^(https?://)?(www\\.)?youtube\\.com/watch\\?(.*&)?v=(.*?)(&.*)?$";
regcomp(&expression,regexpression,0);
char * url = "http://www.youtube.com/watch?v=HereBeVideoId";
if(regexec(&expression, url, 0, NULL, 0)){
printf("Url %s not a valid video.\n",url);
return;
}
return 0;
}

Add REG_EXTENDED flag to regcomp() function:
regcomp(&expression,regexpression,REG_EXTENDED);

Related

How can I include a variable in remove() function? I'm trying to include an environment variable in the function

I'm attempting to learn the remove() function in C, and I want to make a program with first gets the environmental variable with getenv() function, then uses it inside the code.
However, I get the error
"too many arguments to function remove()".
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* a = getenv("USERPROFILE");
remove("%s/Desktop/remove.txt", a);
return 0;
}
If you are simply trying to combine them this should work.
I commented out some lines and put a printf so you can run it to see the result.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXPATH 256
int main()
{
//char* a = getenv("USERPROFILE");
char* a = "userprofile";
char path[MAXPATH];
strcpy(path,a);
strcat(path,"/Desktop/remove.txt");
//remove(path);
printf("PATH: %s",path);
return 0;
}

Termcap "cl" command doesn't clear screen

I can't seem to get termcap's "cl" command to work, but the terminal escape code does.
For example:
#include <termcap.h>
#include <stdio.h>
int main()
{
tputs(tgetstr("cl", NULL), 1, putchar);
}
This doesn't change the terminal. But when I run:
#include <stdio.h>
int main()
{
printf("\e[2J");
}
or if I call echo `tput cl`
The terminal is cleared.
Why does this happen? Shouldn't termcap give that same escape code?
EDIT: Fixed writing characters
EDIT2: It's because i didn't call tgetent() before calling tgetstr(). Thanks guys!
Before interrogating with tgetstr(), you need to find the description of the user's terminal with tgetent():
#include <stdio.h>
#include <stdlib.h> // getenv
#include <termcap.h> // tgetent tgetstr
int main(void)
{
char buf[1024];
char *str;
tgetent(buf, getenv("TERM"));
str = tgetstr("cl", NULL);
fputs(str, stdout);
return 0;
}
Compile with -ltermcap

Linux terminal, how to pass to an argument to another argument C executable

I wrote two little programs in C, crypt and decrypt.
I can call from the terminal:
./crypt some_argument it works.
But I want to pass to decrypt the output of crypt.
I already tried:
./decrypt $(./crypt hello) does not work
./crypt hello | ./decrypt does not work
Source code:
Crypt:
#include <stdio.h>
#include <stdlib.h>
#define CRYPT_KEY 5
char *crypto(char *str) {
char *tmp_adr = str;
while (*str != 0) {
*str += CRYPT_KEY;
str++;
}
return tmp_adr;
}
int main(int argc, char *argv[]) {
printf("Crypted message: %s\n", crypto(argv[1]));
}
Decypt is the same, but with a minus here:
*str -= CRYPT_KEY;
Someone know how to do that?
The output contains spaces. You need to quote it if you want everything in argv[1].
i.e. ./decrypt "$(./crypt some_argument)"

Setting Immutable Flag using ioctl() in C

I have attempted to make a script that creates a file and then sets it as immutable similar to the chattr +i command for linux. The script compiles (with gcc), runs and the file is created. However the file itself is not immutable and can be removed with a simple rm -f. I have attempted to stacktrace where chattr is called and I found a function called ioctl. I then used what little information I could gather and came up with what I have below. I narrowed it down from ext2_fs.h but it just doesn't seem to work. I've clearly overlooked something.
Updates to previous entry: Compiles but returns -1 on ioctl() function. Bad address shown with perror().
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
int main()
{
FILE *fp;
char shovel[16] = "I have a shovel!";
fp = fopen("/shovel.txt", "w+");
fwrite(shovel, sizeof(shovel[0]), sizeof(shovel)/sizeof(shovel[0]), fp);
ioctl(fileno(fp), FS_IOC_SETFLAGS, 0x00000010);
fclose(fp);
}
Any help appreciated.
You are using the right ioctl command, but you're passing it the wrong arguments.
The manpage for ioctl_list(2) shows that FS_IOC_SETFLAGS expects to receive a pointer to int (an int *), yet you're passing it an integer literal (hence the Bad Address error).
The fact that you don't to any error checking whatsoever is also not helping.
The correct flag to pass to FS_IOC_SETFLAGS is a pointer holding the value EXT2_IMMUTABLE_FL, which is defined in ext2fs/ext2_fs.h (some older / different Linux distributions seem to have it under linux/ext2_fs.h), so you'll need to #include <ext2fs/etx2_fs.h>. Make sure to install e2fslibs-dev (and probably you'll need linux-headers too).
This code is working:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <ext2fs/ext2_fs.h>
int main()
{
FILE *fp;
char shovel[16] = "I have a shovel!";
if ((fp = fopen("shovel.txt", "w+")) == NULL) {
perror("fopen(3) error");
exit(EXIT_FAILURE);
}
fwrite(shovel, sizeof(shovel[0]), sizeof(shovel)/sizeof(shovel[0]), fp);
int val = EXT2_IMMUTABLE_FL;
if (ioctl(fileno(fp), FS_IOC_SETFLAGS, &val) < 0)
perror("ioctl(2) error");
fclose(fp);
return 0;
}
Remember to run this as root.
UPDATE:
As Giuseppe Guerrini suggests in his answer, you might want to use FS_IMMUTABLE_FL instead, and you won't need to include ext2_fs.h:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
int main()
{
FILE *fp;
char shovel[16] = "I have a shovel!";
if ((fp = fopen("shovel.txt", "w+")) == NULL) {
perror("fopen(3) error");
exit(EXIT_FAILURE);
}
fwrite(shovel, sizeof(shovel[0]), sizeof(shovel)/sizeof(shovel[0]), fp);
int val = FS_IMMUTABLE_FL;
if (ioctl(fileno(fp), FS_IOC_SETFLAGS, &val) < 0)
perror("ioctl(2) error");
fclose(fp);
return 0;
}
The main problem is that the ioctl wants a pointer to the mask, not a direct constant. You have to define a int variable, store the mask (0x10) in it and pass its address as third argument of ioctl.
Also, I'd add some hints:
other programs to change attributes are used to use low-level I/O directly (open, close...). Also, the file is usually opened with O_RDONLY.
Use FS_IMMUTABLE_FL istead the raw constant.
Get the current attribute mask first (FS_IOC_SETFLAGS) and mask it with the new flag, so other settings are not lost by the service.

It seems setlocale() doesn't work in a linked library

#include <qapplication.h>
#include <qmainwindow.h>
#include "mainwindow.hpp"
#include "../RegisterOfErrors.hpp"
#include <clocale>
extern std::string* Error::DescriptionOfErrors;
int main (int argc, char *argv[])
{
std::locale::global(std::locale("en_US"));
setlocale(LC_ALL, "en_US");
FILE *conf = fopen("dupa.txt", "r");
float dupa;
fscanf(conf, "%f", &dupa);
printf("%f\n", dupa);
Error::setDescriptionOfErrors();
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
My default locales are "es_ES", so "," is a decimal point.
It is my code. In the file "dupa.txt" is a number "1.0344" and it works correctly. However, deeper in the code I'm using the fann library, which is linked in g++ by "-ldoublefann" and read some data from files, and in this library works only ",".
The problem was caused by Qt.
There is some code
#include "doublefann.h"
#include "fann_cpp.h"
#include <clocale>
int main() {
setlocale(LC_ALL, "en_US");
const int max_neurons = 20;
const int neurons_between_reports = 1;
const double desired_error = 0.0001;
FANN::neural_net* repetition_ann;
repetition_ann = new FANN::neural_net();
repetition_ann->create_shortcut(2, 2, 1);
repetition_ann->cascadetrain_on_file("train.dat", max_neurons, neurons_between_reports, desired_error);
}
And this code works as I expect - It reads numbers, which have ".", from file "train.dat" ad prints numbers with ".".
The difference between those cases: in the first case the similiar code is somewhere in qtapplication, this code is independent.
Qt sets own locales, so the solution is adding a line: std::locale::global(std::locale("en_US")); and #include <QtCore>

Resources