I am looking for a way to determine if a certain file contains a certain string. It can be a system call or a C function, it doesn't matter.
I tried with grep, but it doesnt return anything
//name is the directory entry name
char grepcmd[150];
strcpy(grepcmd,"grep -c hello ");
strcat(grepcmd, name);
int status = system(grepcmd);
You are doing well. status should be zero if your given file with name name contains hello string. Otherwise it should be nonzero value.
If you're up for system calls, then just mmap() the file and call something like strnstr(). (You won't be able to call the real strnstr() since it will stop at any \0 in your file, so you'll have to write your own.)
Related
I am trying to get the HDD serial key of a windows PC using system() command and save that number in a text (.txt) file with a file name that user chooses. Everything is working fine before the system() command, but the system() command is NOT changing the file name,that is, instead of naming the file after the user choice, it is just naming it after "contract_file_name" with no extension. For example: if I give file name: blahblah , it's supposed to create a text file with the name "blahblah.txt" (containing HDD serial Key), but instead it's creating a file with "contract_file_name".
Here is code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char contract_file_name[100];
FILE *fp1 ;
filename:
printf("Please Give an APPROPRIATE name for SENDER-RECEIVER CONTRACT file. Please Don't use any .txt extension\nFILE NAME: ");
gets(contract_file_name);
strcat(contract_file_name,".txt");
if((fp1=fopen(contract_file_name,"r")))
{
printf("A Contract File with %s already EXITS.Please Choose another name\n".contract_file_name);
goto filename;
}
else
{
fp1= fopen(contract_file_name,"w");
fprintf(fp1,"$Sender: %s\n",getenv("USERNAME"));
fclose(fp1);
system("wmic path win32_physicalmedia get SerialNumber >> contract_file_name"); //Having problem in this line,I think.
fp1 = fopen("contract_file_name","a");
fprintf(fp1,"\n");
fclose(fp1);
}
return 0;
}
I can feel that the problem is with my method system() command, But can't find any solution.Can anyone please suggest me how to FIX this problem?
Thanks in Advance.
The problem is not with the system function (which you shouldn't be using for this task anyway), but with your misunderstanding how string substitution works.
You have a variable contract_file_name of type "array of 100 char" and apparently expect every occurance of "contract_file_name" inside a string to automatically being replaced. This is called "variable expansion" and is in fact supported in some languages. Most notably shell and Perl. However you actually have to mark the variables in a string for replacement (usually by prepending a $ sign). That does not work in C! C is a very frugal language and doesn't come with that feature.
Anyway your program immediately reads back the file and hence using a fixed filename or a filename at all is a bad idea anyway (think about what might happen if several instances of your program get run at the same time; can you prove that all parts in play are idempotent? probably not).
Instead you should run wmic with popen. With popen the output of wmic is written to a FIFO which you can read directy as if it were a file, without a file ever being written to a disk: https://msdn.microsoft.com/en-us/library/96ayss4b.aspx
You have contract_file_name is a literal string in your system call. You have to put the value of the variable in the string first, something like
char tmp[100+50];
sprintf(tmp, "wmic path win32_physicalmedia get SerialNumber >> %s", contract_file_name);
system(tmp);
You should also limit what you read into contract_file_name to 99 characters.
Could someone help me in writing a program that has to compile all the files in the directory and report error, if any. For which my program has to get the list of all files under the folder with its full path and store it in a temp-table and then it has to loop through the temp table and compile the files.
Below is a very rough start.
Look for more info around the COMPILE statement and the COMPILER system handle in the online help (F1).
Be aware that compiling requires you to have a developer license installed. Without it the COMPILE statement will fail.
DEFINE VARIABLE cDir AS CHARACTER NO-UNDO.
DEFINE VARIABLE cFile AS CHARACTER NO-UNDO FORMAT "x(30)".
ASSIGN
cDir = "c:\temp\".
INPUT FROM OS-DIR(cDir).
REPEAT:
IMPORT cFile.
IF cFile MATCHES "*..p" THEN DO:
COMPILE VALUE(cDir + cFile) SAVE NO-ERROR.
IF COMPILER:ERROR THEN DO:
DISPLAY
cFile
COMPILER:GET-MESSAGE(1) FORMAT "x(60)"
WITH FRAME frame1 WIDTH 300 20 DOWN.
END.
END.
END.
INPUT CLOSE.
Since the comment wouldn't let me paste this much into it... using INPUT FROM OS-DIR returns all of the files and directories under a directory. You can use this information to keep going down the directory tree to find all sub directories
OS-DIR documentation:
Sometimes, rather than reading the contents of a file, you want to read a list of the files in a directory. You can use the OS–DIR option of the INPUT FROM statement for this purpose.
Each line read from OS–DIR contains three values:
*The simple (base) name of the file.
*The full pathname of the file.
*A string value containing one or more attribute characters. These characters indicate the type of the file and its status.
Every file has one of the following attribute characters:
*F — Regular file or FIFO pipe
*D — Directory
*S — Special device
*X — Unknown file type
In addition, the attribute string for each file might contain one or more of the following attribute characters:
*H — Hidden file
*L — Symbolic link
*P — Pipe file
The tokens are returned in the standard ABL format that can be read by the IMPORT or SET statements.
I am wondering if I could pass file as an argument in a main function? I mean not a name of the file but file itself.
Not unless something external (e.g. a bash script) reads in the file and adds it as an argument. If there is a binary 0 in the file, that would be interpreted as the end of string.
You can achieve something similar using input redirection, where the contents of a file is redirected to stdin, e.g.
myprogram < myTextFile
You would then be able to read the contents of the file by reading from stdin.
You could, as long as there's no 0 bytes in the file.
Also, you shouldn't.
If you want to know how to do that, it depends on the operating system.
I have this command line:> write_strings "Hello World!" a.txt b.txt dir/a.txt.
all the elements (command, string, file names) go into an array of char pointer. how can I take an element and check if it's a string or a file name?
I don't mean the exact code lines, buts just need the idea. the program should return an error if there's no string.
You can use an API such as stat or access to check if the file pointed to by a path exists. There is no fundamental distinction between filepaths and regular strings when they are passed to your process.
If you're using the standard main(int argc, char *argv[]) convention, you can loop through argv, checking each one to see if it's a file via one of the previously-mentioned system calls.
Every string that can be passed on a command line is a potential pathname, since the only restriction in both cases is that there can't be any NULs.
A program with a command line syntax in which a specific argument might or might not be used as a pathname (depending on some vague definition of "filename-ish strings" or even a file existence test) is a bad design. Each argument should have a meaning defined by its order in the argument list, or by being associated with an option like -m msg or -o outputfile.
A well-behaved unix program will let the user create a file called Hello world! if he wants.
not regarding how meaningful the program might or might not be - you can compare the single characters of your char *argv[] by looping through them via argv[i][j]. If every string includes a ".txt" you do not have a string, which is not a filename in your context
i trying make a custom method what causes return a char with system output.
the pseudocode like this.
char *my_Out(char *in ){
in = system ("ping %s",in);
return in;
}
thanks for the help.
You can use popen, which returns you a stream that you can read the output from. By reading until end-of-file, into a string (probably one that dynamically grows as necessary), you can implement what you're asking for.
A few things
system() is not a printf style function. You'll need to use sprintf() to create your argument before.
system()'s return value is an int, non a char
It's generally not a good idea to overwrite function parameters.
What are you trying to do? It looks like all this function does is run ping (which, without the -c argument, will never finish running on linux).
Duplicate the stdout to some other file descriptor by using dup2.After the execution of the command read all the lines from the file using that file descriptor and return it.