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.
Related
steps:
Let's say I have a C program inputFileName.c
I run inputFileName with input redirection such as ./inputFileName < file
How can I print the name of the file in my C program that I have typed in the terminal as an input redirection file?
The input redirection is a function of the shell. Your inputFileName executable see this as standard input. Depending on the exact operating system, you may be able to use system-specific functions to get the information you want, but there is not a standard means of doing so.
Input redirection can be achieved not only with the '<' symbol, but also with '|'.
program < filename
is equivalent to
cat filename | program
From there, one could go to
cat file1 file2 file3 | program
You begin to see why the initial 'stdin' for an executable cannot and does not have a "filename" associated with it.
If input comes from a pipe, there can't be an associated filename. Also if the file has been deleted or moved before closing the file descriptor, there is no associated filename. A file can have multiple names. In that case there are multiple filenames.
Given that, the "associated filename" of a file descriptor doesn't really make much sense. And even if you could get that info, using the filename in any way might make race conditions an issue.
The linux kernel does try to track an associated filename if a file descriptor was created by opening a file. But the keyword here is "tries".
If you are running Linux, you can find the filenname for standard input as a symlink under "/proc/self/fd/0". Just remember that you should not rely on that name for anything more than debug or display purposes.
This code does not open file properly, it returns no such file or directory, although the path and privilege are there and no other program is using the file. How can I fix the error? I tried swapping the path and moving the file, the error is there still.
char string[105];
FILE* file = fopen("C:\\Users\\Public\\Documents\\a.txt", "r");
while (fgets(string, 100, file)) {
printf("%s", string);
}
It can be surprisingly tricky to open a simple file! Lots of things can go wrong. I recommend writing slightly more verbose code, like this:
#include <string.h>
#include <errno.h>
char* filename = "C:\\Users\\Public\\Documents\\a.txt";
char string[105];
FILE* file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "can't open %s: %s\n", filename, strerror(errno));
exit(1);
}
while (fgets(string, 100, file)) {
printf("%s", string);
}
The point is that the error message prints out both the name of the file it tried but failed to open, and the actual reason it couldn't open it. (Also, by storing the filename in a variable, you make it absolutely certain that the filename it prints in the error message is the filename it tried but failed to open.) It sounds like you already know that the error was "no such file or directory", but I'm not sure how you know this.
Even though I've been programming in C for a long time, sometimes I still have this problem. One thing I'll sometimes do is use my mouse to copy the exact filename string printed in the error message, the file the program said it couldn't open, the file I'm sure is really there, and paste it into a terminal window (or CMD or Powershell if you're on Windows), along with a directory-listing command, to see if the operating system can actually see the file. That is, for your example, the command I'd run is
dir C:\Users\Public\Documents\a.txt
but the point is that I would not actually type the pathname "C:\Users\Public\Documents\a.txt", instead I would copy and paste it out of the error message that the program printed. Sometimes there are surprising little impossible-to-spot differences between the filename you thought it was trying to open, versus the filename it was actually trying to open, and this exercise is a good way to let the computer help you find those differences.
Remember, too, that you'll get the error "No such file or directory" if there's no file by that name in the directory, or if the directory isn't there at all. For example, if you're trying to open the path
C:\Users\Public\Documents\a.txt
and the file a.txt keeps not being there, and you keep checking your home directory
C:\Users\Donkey\Documents
and you keep seeing that the file is there, it can be surprisingly easy to overlook what the real problem is. :-)
Addendum: You might be having an issue with the different Unix/Linux versus Windows file path separators, that is, / versus \. Usually, on a Windows machine, it's safest to use \, as you've done. (One very frequent mistake is to forget to double the backslashes, but it looks like you got that right.) Depending on your programming environment, if there's some level of Unix emulation going on, you can sometimes use Unix-style /, and it will automatically translate to \ for you. I've never heard of a situation where using \ made it not work (which is a possibility being explored in the comments), but you might experiment with that, perhaps trying
char* filename = "/c/Users/Public/Documents/a.txt";
or (less likely)
char* filename = "C:/Users/Public/Documents/a.txt";
I'm quite new to C programming, but I'm starting to get the hang of it.
For a school assignment, I have written a code in C to play Blackjack.
One of the requirements for the assignment, is that is has to have an option that saves the entire output (everything that's shown in cmd when the program is build and run).
I can't find how to do this anywhere.
Is there a way to write the entire output into a file?
Thanks in advance!
There are 3 ways to achieve what you want.
Use a file. This is the way I recommend. You will need the functions fopen to open a file and enter link description here to print the data in the file. I suggest you read the documentation of the functions in the links and look at the examples.
Redirect stdout to a file using freopen. This basically puts everything that you see now in the console in a file, by adding just one line.
Redirect the output of the program in a file. This is more a shell thing than a C programming technique, but I think it is worth mentioning. In an *NIX environment, the command ./a.out > file.txt will redirect the output of a.out to a file called file.txt in a similar manner freopen does.
You can pipe the stdout and stderr to a file when you build and run. For example, on Linux using the bash shell you can do try this (where the "build_script" is what you use to build and the "a.exe" is the program name):
$ ./build_script >& build_out.txt
$ ./a.exe >& run_out.txt &
The ">&" tells bash to pipe both stdout and stderr to the file. The final "&" in the second line tells bash to run the program in the background. It's hard to tell if this answer will suit your purposes since it's not clear exactly how the game is played from what you have posted. E.g., if you need to use stdin/stdout to play the game then maybe piping the "a.exe" stdout to a file might not work...
I'm assuming simple output redirection is not an option:
$ app > file.txt
Probably, you are using printf to print data to console. Instead of printf, you can use fprintf. fprintf can write data to an arbitrary file, just like printf does to the standard output (which is also a file), in this case the console.
You must first open the file where you will write the output. The command fopen will do this for you:
// this will open or create the file as text to write data.
FILE *f = fopen("my-file.txt", "w");
With the f variable (which you should check for NULL in case of error), you can pass it to fprintf to write data:
fprintf(f, "my super string: %s", string);
Note that despite the first argument being a FILE*, everything else behaves like printf. Actually you can think of printf as a wrapper where the first argument of the fprintf is always stdout.
Do not forget to close your file after you write data!
fclose(f);
This can be done once, after all the data is written to file.
Check the man pages for more info about these commands.
There are more complex (not that much actually) ways of accomplishing this, like using freopen, but I'm leaving this out of the answer. If you need more, update your answer.
EDIT
In your comment, you said you must save or not the output to a file at the end of the program. Well, the file management stuff above you still be usefull. The changes are the following:
You must store the output somewhere in order to decide whether to write to a file or not at the end of the program. Probably you are doing some data formatting with printf. You will have to change your calls from printf to snprintf. This command will write your data to a string, just as printf does prior to output it to the stdout, but it will skip the print-to-output- part.
Then, store the buffer at a list of strings and at the end of the program you write this list to the file or not.
This has some complications: you need a list of strings (a dynamically allocated array of arrays will be enough, actually); how big must your buffer be?
snprintf will return the size required to print the passed data to the buffer, no matter if the buffer is larger or smaller then the given one. But, if it is smaller, you will have to increase its size (reallocating it) and call again snprintf:
char *buffer = malloc(sizeof(char) * 41); // 40 chars + \0!
int size;
if ( size = snprintf(buffer, 41, "your format here", args) > 40 ) {
buffer = realloc(buffer, sizeof(char) * (size + 1));
snprintf(buffer, size + 1, "your format here", args);
}
// now your buffer have the correct data!
// print it to stdout!
puts(buffer);
// store it at the string list.
// execise!
Is left as an exercise wrapping this piece of code in a command to avoid repeat it everywhere you print anything. Also, it is an exercise to create the list of strings.
When you decide to write data to file, instead of use fprintf you can use fputs, as data is already formatted.
I don't know if there is an easier way. I think not.
I am working with command prompt features with a simple program to generate a text file in C. Here is the program:
#include <stdio.h>
int main(void)
{
char buf[80];
fgets(buf, 30, stdin);
printf("the input was %s\n", buf);
return 0;
}
My programming book is wanting to show how to play with the command prompt to make text files from programs, and instructs typing the word 'redirect' followed by '>' then the name of the program name with '.txt'. as below:
redirect> programname.txt
Now this IS generating a file 'programname.txt' on the desktop, but it is empty. The book purports that recipe should allow me to enter a string (as the program is DESIGNED to do) and that this string will be inside a generated programname.txt file. Also, there is a warning in the command line: "not recognized as an internal or external command". I've had this schpill before, but the text file generation did WORK, in that it did generate the .txt file. What am I missing here, for this program to work as intended?
You seem to be confused by the fact that it is not your program, but the shell which creates the file programname.txt, before it even tries to run your program.
And after the first succeeded and created an empty file, the latter probably fails because there is no command redirect in your PATH or such a thing exists as a builtin in your shell, as has already been suggested.
The usual way to perform output redirection in a shell is to use the > filename, but not with redirect before it contrary to what you say. The thing that comes before the > is the command to be redirected.
So, let's say you compile your program and save it as foo in the current directory (e.g. cc -o foo myprogram.c). In that case, you can redirect its output by saying:
./foo > filename.txt
I have to write code in C to extract a password protected rar file in windows. I don't have any clue about how to do this. can anybody suggest me something or provide a sample piece of code? I will be very thankful.
EDIT:
This is the code I am using to open the rar file.In the system command ranjit is the password. It's giving the error undefined symbol_system in module+thefile name. Can anybody help me?? I am struggling on this since two days.
EDIT: This code opens the archive but do not extract it. If I uses the unrar command in command line, it extracts the file. What I should I do?
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv)
{
char file[20];
char file2[50] = "F:\\Program Files\\WinRAR\\unrar.exe";
printf("enter the name of the rar file : ");
gets(file);
puts(file);
system(("%s e -p ranjit %s >C:\stdout.log 2>C:\stderr.log",file2, file));
getchar();
return 0;
}
In addition to what karlphilip's suggestions there's also a couple of potentialliy interesting looking resources at http://www.rarlabs.com/rar_add.htm.
In particular I am thinking UnRAR.dll and UnRAR source may be relevant. I can't really check it out at the momment though.
Using unrar library - extracting files into a filestream buffer
But if you're looking for a pure C solution, take a look at: http://www.unrarlib.org/
Quote from their FAQ: The URARFileLib (short name for UniquE RAR File Library, also called unrarlib) is a free library for C programmers to access RAR archives.
Another approach, which I just tested successfully, doesn't require the use of external libraries to decompress rar files. Use system() to invoke a command-line tool (such as unrar ) already installed on your system to do the job:
system("unrar x -ppassword protected_file.rar /destination_directory");
For instance, let's say the protected file was named file.rar, the password was 1234 and the destination directory was /home/user, you would call system() with the following parameters:
system("unrar x -p1234 file.rar /home/user/");