How to pass system command containing quotes in a C string - c

Apologies if this has been answered, but I haven't found an answer that solves my problem.
I'm trying to pass a system string in C: the bash version of the command is
grep -w "dog\|animal" myfile
I have the following C code:
char str[50] ="dog\\|animal";
char file[50]="myfile";
char buf[20];
snprintf(buf, sizeof(buf), "grep -w \"%s\" %s",str,file);
system(buf);
When I compile and run it I am given this error:
sh: 1: Syntax error: Unterminated quoted string
Minimum example:
#include <stdio.h>
#include <string.h>
int main(){
char str[50] ="dog\\|animal";
char file[50]="myfile";
char buf[20];
snprintf(buf, sizeof(buf), "grep -w \"%s\" %s",str,file);
system(buf);
}

Transferring comment into answer.
You have two component strings size 50, and you try to squeeze them into a 20-byte target. You should be using perhaps 200 instead of 20.
At any rate, 20 is too short. You have 12 characters of overhead plus 6 in the file name and 11 in the match pattern. That's not going to lead to happiness. (Note that if you had checked the return from snprintf(), it would tell you it needs more space than you gave it.). And the most elementary debug technique would add printf("[%s]\n", buf) to show you what is being executed.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char str[50] = "dog\\|animal";
char file[50] = "myfile";
char buf[20];
int size;
if ((size = snprintf(buf, sizeof(buf), "grep -w \"%s\" %s", str, file)) >= (int)sizeof(buf))
printf("Oops! (%d) ", size);
printf("[%s]\n", buf);
system(buf);
return 0;
}
Example output (program name sh11):
$ ./sh11
Oops! (28) [grep -w "dog\|anima]
sh: -c: line 0: unexpected EOF while looking for matching `"'
sh: -c: line 1: syntax error: unexpected end of file
$
Note that the size returned by sprintf() does not include the null terminator; the buffer needs to be at least 29 bytes to hold everything.

Related

Print command line parameter on console

I want to pass a file name to my programm. If I type it in the terminal it works. But if I pass it as a command line parameter it doesn`t print the string in the end. Just something like: "²☺"
Any ideas why?
#include <stdio.h>
int main(int argc, char* argv[]){
char *nameDatei[100];
if(argv[1] != NULL) {
nameDatei[100] = argv[1];
} else {
printf("type in the name of the file: ");
scanf("%s", nameDatei);
}
printf("%s", &nameDatei);
return 0;
}
It only works "by accident" when you type the name at the terminal, and that's because you are either ignoring compiler warnings or using an obsolete compiler (any compiler which is not complaining about the code is obsolescent, though GCC 11.2.0 seems to accept it unless you pass warning options such as -Wall -Wextra -Werror).
You pass a char *(*)[100] to printf() but tell it that the argument is a char *
You pass a char ** to scanf() but tell it that the argument is a char *
You try to access element 100 of an array of size 100, which is one too many.
You happen to have 100 * sizeof(char *) bytes to hold the name, which is where the accident comes in, but that's not the correct type.
You need code more like:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *nameDatei;
char nameBuffer[100];
if (argv[1] != NULL)
nameDatei = argv[1];
else
{
printf("type in the name of the file: ");
if (scanf("%99s", nameBuffer) != 1)
{
fprintf(stderr, "failed to read file name\n");
exit(EXIT_FAILURE);
}
nameDatei = nameBuffer;
}
printf("%s\n", nameDatei);
return 0;
}
I called the source cla61.c and the program cla61. A couple of sample runs:
$ cla61 abyssinian-coffee
abyssinian-coffee
$ cla61
type in the name of the file: abyssinian-coffee
abyssinian-coffee
$
Don't copy command-line arguments unless you are going to modify them. But it's legitimate to make a new variable point to a command-line argument. And when there isn't a command-line argument, you need to allocate space for the replacement value — the value read from the terminal in this example.

What is ./nqt in C programming and how do i change file without changing them in the code

So i trying to input multiple files in the assigned program.
My input file code is as such:
int read_File(int *hp, int *d, int *s, char t[])
{
FILE *infile;
infile = fopen("input1.txt", "r");
if (!infile)
{
return 0;
}
else
{
fscanf(infile, "%d", hp);
fscanf(infile, "%d", d);
fscanf(infile, "%d", s);
fscanf(infile, "%s", t);
fclose(infile);
return 1;
}
i did
$>gcc assignedProgram.c -o nqt
$>./nqt input1.txt
but if i want to read input2.txt, i have to change from input1.txt to input2.txt in the codes. Is there anyway to bypass that and read input2.txt without changing from input1.txt to input2.txt in the codes
like when i tried ./nqt input1.txt => it's normal
BUT ./nqt input2.txt it's segmentation fault:11
I tried:
to change "input1.txt" in the codes to "nqt" but that was a dumb idea
and BTW: what is ./nqt
Please help me!
You must write main() as one of the equivalent forms below
int main(int argc, char **argv) { /*...*/ }
int main(int argc, char *argv[]) { /*...*/ }
so that argc and argv are set up by your environment to proper values.
For example
$ ./nqt input.txt
^^^^^ ^^^^^^^^^ --> 1
\\\\\-------------> 0
Translates in your program to
argc == 2
argv[0] ==> pointer to "./nqt"
argv[1] ==> pointer to "input.txt"
argv[2] ==> NULL
When it comes to nqt, it is the name of the program you specified with -o flag when compiling: gcc assignedProgram.c -o nqt. In order to run the program, you need to use ./ prefix, thus ./nqt means "run the program called nqt".
If you want to pass the name of the file as an argument, you should tell main function to accept command line arguments: int argc and char* argv[] (you can read about it here). Then the name of the file you will pass by running ./nqt <filename> would be stored in argv[1], which you should pass to read_File function as an argument.

Not matches for working regex in c

I want to match the regex (?<=SEARCH_THIS=").+(?<!"\n) in C with PCRE.
However, the following code doesn't work as expected.
#include <pcreposix.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){
regex_t re;
regmatch_t matches[2];
char *regex = "(?<=SEARCH_THIS=\").+(?<!\"\n)";
char *file = "NO_MATCH=\"0\"\nSOMETHING_ELSE=\"1\"\nSOME_STUFF=\"1\"\nSEARCH_THIS=\"gimme that\"\nNOT_THIS=\"foobar\"\nTHIS_NEITHER=\"test\"\n";
puts("compiling regex");
int compErr = regcomp(&re, regex, REG_NOSUB | REG_EXTENDED);
if(compErr != 0){
char buffer[128];
regerror(compErr, &re, buffer, 100);
printf("regcomp failed: %s\n", buffer);
return 0;
}
puts("executing regex");
int err = regexec(&re, file, 2, matches, 0);
if(err == 0){
puts("no error");
printf("heres the match: [.%*s]",matches[0].rm_eo-matches[0].rm_so,file+matches[0].rm_so);
} else {
puts("some error here!");
char buffer[128];
regerror(err, &re, buffer, 100);
printf("regexec failed: %s\n", buffer);
}
return 0;
}
The console output is:
compiling regex
executing regex
some error here!
regexec failed: No match
I verified the functionality of this regex here
Any idea what is going wrong here?
EDIT #1
Compiler Version
$ arm-merlin-linux-uclibc-gcc --version
arm-merlin-linux-uclibc-gcc (GCC) 4.2.1
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Compile Command
$ arm-merlin-linux-uclibc-gcc -lpcre ./re_test.c -o re_test.o
There are actually a few issues with your code.
First, you use %*s in an attempt to restrict the length of the printed string. However, the integer width before the s formatter is the minimum length of what gets printed; if the corresponding string's length is less than what's given, it'll be padded with spaces. If the length is greater than what's given, it'll just output the whole string. You'll need some other method of restricting the length of the outputted string (just avoid modifying *file, because file points to a constant string).
Second, you specify the REG_NOSUB option in your regcomp call, but according to the man page, this means that no substring positions are stored in the pmatch argument - thus, even if your regexec did work, the following printf would be using uninitialized values (which is undefined behavior).
Finally, I suspect the problem is that the \" and \n characters need to be doubly-escaped; i.e. you need to use \\\" and \\n in your regex string. While the code you gave worked for me (Ubuntu 14.04 x64), the doubly-escaped version also works.
Taking all of this into account, this is the output I get:
compiling regex
executing regex
no error
heres the match: [.gimme that"]

Need help on simple C command line argument

I don't really know how to explain this but here's my problem:
I am trying to make my program accept command line arguments and then run a program via. the Linux command line (CentOS 6).
Heres the main function:
int main(int argc, char *argv[])
I am trying to run a Linux program, here's the code:
system("nmap -sT -p 19 1.1.1.* -oG - | grep 19/open > temp");
I want to replace '1.1.1.*' with the first argument I input into my C program, Ex:
system("nmap -sT -p 19 ", (argv[1]) "-oG - | grep 19/open > temp");
I have tried multiple ways and none seemed to work.
To sum it up, i'm trying to take the first argument I input into my program and use it in replace of the '1.1.1.*' in the system function. I have no idea on how to do this, I'm new to C programming. Thank you all replies are appreciated.
snprintf is the safest way to do this, this is a simple example without any checking of argc etc...:
#include <string.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
char buf[200] ;
char str1[] = "nmap -sT -p 19 ";
char str2[] = " -oG - | grep 19/open > temp";
snprintf(buf, 200, "%s%s%s", str1, argv[1], str2);
printf( "%s\n", buf ) ;;
}
Just use the following syntax to accept command line arguments in Linux.
./program arg1 arg2

GCC compilation errors related to while statement [duplicate]

This question already has an answer here:
Lots of stray errors - "error: stray ‘\210’ in program in C++" [duplicate]
(1 answer)
Closed 8 years ago.
When trying to compile this short C program using GCC I get these errors:
expected ‘)’ before numeric constant
make: *** [file3_5.o] Error 1
stray ‘\210’ in program
stray ‘\227’ in program
stray ‘\342’ in program
Eclipse (Juno) points all of these errors to one line of code:
while(fgets(line ,STRSIZE∗NFIELDS, fp))
Using the following statement to compile:
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"file3_5.d" -MT"file3_5.d" -o "file3_5.o" "../file3_5.c"
Here is the program I am trying to compile:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STRSIZE 100
#define NFIELDS 9
int main()
{
char inputfile[]= "/home/ty/workspace/OpenCoursware_Exercises/Assign_ /stateoutflow0708.txt";
/* define all of the fields */
char state_code_org[STRSIZE];
char country_code_org[STRSIZE];
char state_code_dest[STRSIZE];
char country_code_dest[STRSIZE];
char state_abbrv[STRSIZE];
char state_name[STRSIZE];
char line[STRSIZE*NFIELDS];
int return_num = 0;
int exmpt_num=0;
int aggr_agi= 0;
long total=0;
/* file related */
int fields_read = 0;
FILE* fp=fopen(inputfile,"r");
if(fp==NULL)
{
fprintf(stderr, "Cannot open file\n");
exit(-1);
}
/* skip first line */
fgets(line, STRSIZE*NFIELDS,fp);
/* print the header */
printf ("%-30s,%6s\n","STATE","TOTAL");
printf("---------------------------------------\n");
while(fgets(line ,STRSIZE∗NFIELDS, fp))
{
/* parse the fields */
fields_read=sscanf(line,"%s %s %s %s %s %s %d %d %d",
state_code_org,
country_code_org,
state_code_dest,
country_code_dest,
state_abbrv,
state_name,
&return_num,
&exmpt_num,
&aggr_agi);
if(strcmp(state_code_org, "\"25\"")==0)
{
printf("%-30s, %6d\n", state_name, aggr_agi);
total += aggr_agi;
}
}
/* print the header */
printf(" ----------------------------------------\n");
printf("%-30s,%6lu\n","TOTAL",total);
fclose(fp);
return 0;
}
Your ∗ is not the mulitplication operator * , they may look similar, but are different characters, and gcc doesn't recognize the ∗
while(fgets(line ,STRSIZE∗NFIELDS, fp))
^
^
Should be
while(fgets(line ,STRSIZE*NFIELDS, fp))
^
^
(Whether you see a difference between the two depends on the font used to display the characters).
The ∗ in the first one is not the character used for the multiplication operator, it is this character here.
Your "*" character in STRSIZE*NFIELDS is not the regular * (ascii value 42) but an unicode character "ASTERISK OPERATOR" : http://www.fileformat.info/info/unicode/char/2217/index.htm
That's what the compiler is trying to tell you by complaining about stray characters in the source.

Resources