C programming - opening from a specific windows directory - c

I fairly new to the C programming language. I am writing a program that will eventually read through mp3 files from a user inputted directory, and sort the mp3's into artist/album folders by utilizing the metadata in the id3's. I am accessing the user's directory using the system() function call, and generating a .txt file containing all of the mp3's in that directory. However I am running into problems when trying to access the first mp3 file. I am building the mp3 file's path, but the file will not open. The file DOES open when I hard code the path.
#include <stdio.h>
#include <string.h>
struct FILE_head
{
char file_id[3];
char version[2];
char flags;
char size[4];
};
int main()
{
//declare vars
char cd[1200];
char mp3[200];
char dir[1000];
char mp3_path[1200];
FILE *list_file;
FILE *mp3_file;
struct FILE_head id3;
char dir_cmd[1300] = "dir ";
char find_cmd[100] = "/b | find \".mp3\" > \"mp3List.txt\"";
int dir_len;
int amt_read;
//main code
while(1)
{
cd[0]='c';
cd[1]='d';
cd[2]=' ';
cd[3]='\0';
printf("Enter the directory where mp3's are located:");
scanf("%s", dir);
strcat(cd, dir);
if(system(cd) == 0) //if directory is valid, break. otherwise stay in loop/reprompt
break;
printf("Valid directory Ex--> c:\\users\\username\\music\n");
}
//build cmd statement
strcat(dir_cmd, dir);
strcat(dir_cmd, find_cmd);
system(dir_cmd);
dir_len = strlen(dir);
strcpy(mp3_path, dir);
printf("%s\n", mp3_path);
list_file = fopen("mp3List.txt", "rb");
if(list_file != NULL)
{
while(fgets(mp3, sizeof(mp3), list_file))
{
printf("%s", mp3);
strcat(mp3_path, mp3);
printf("%s\n", mp3_path);
mp3_path[strlen(mp3_path)-1] = '\0';
mp3_file = fopen(mp3_path, "rb");
if(mp3_file != NULL)
{
printf("in this loop");
fread(&id3, sizeof(id3), 1, mp3_file);
printf("%s\n", id3.file_id);
}
}
}
return 0;
}
This is my first time posting, so if any more information would be helpful please let me know. I realize there might be "better" ways to access directories, but I don't want to use any functions that are not in the C std lib.
This is my output:
C:\Users\Mitchell\Projects>mp3sort.exe Enter the directory where mp3's
are located:c:\users\mitchell\projects\music_test\
c:\users\mitchell\projects\music_test\ 01 - Time to Pretend.mp3
c:\users\mitchell\projects\music_test\01 - Time to Pretend.mp3
01-all_that_remains-this_calling.mp3
01-all_that_remains-this_calling.mp3t\01 - Time to Pretend.mp3
07 Billy Joel - Everybody Loves You Now.mp3 07 Billy Joel - Everybody
Loves You Now.mp3Time to Pretend.mp3
Tears for the Sheep.mp3 Tears for the Sheep.mp3dy Loves You
Now.mp3Time to Pretend.mp3
C:\Users\Mitchell\Projects>
I know that my current build for the all the files after the first isn't correct, but I was just focused on getting the first mp3_path to work. I removed the newline by: mp3_path[strlen(mp3_path)-1] = '\0';

system() executes provided command in subprocess. When you do system ("cd somedir"), cd somedir is executed in child process, thus working directory of your process remains unaltered.
If you want to change your process working directory, use chdir() (or _chdir(), alternatively SetCurrentDirectory if you want to use Windows API) function.
Alternatively, you can avoid changing working directory by prepending directory to file names.

Related

issue executing unix commands using system() in c

I'm currently trying to write a program to accept user input to and execute commands in a unix system, the code compiles but when I run it I get a segmentation fault. I think it might be related to the input data type for the system() function but I can't seem to figure it out
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
char argument[1024];
main() {
fgets(argument, 1024, stdin);
strtok (argument, "\n");
char *command = strcat("cd ", argument);
int response = system(command);
if(response == -1)
{
printf("error executing command");
}
}
I apologise if this seems trivial I don't have much experience with c
You are programming in C in an Unix system.
The language C was written just to write Unix itself. system() was written in C, Unix, Windows, Linux, Android, MacOS, Python, java, everything was written in C at first and still is at the most part.
And you have many shells in Unix and derivatives that just run commands as the user types them.
So to use system() to run a command does not add much. Just another level of indirection, an a big security hole, since your program can be used to do unexpected things by not so good people. Using YOUR program.
An alternative
This is the output of the program below
Current directory is: /home/testing/projects/tcursor
directory changed to '/tmp'
Enter name of directory to create: thing
'/tmp/thing' created
Now changing to newly created folder
Current directory is: '/tmp/thing'
The program just
cwd to /tmp
prompt for the name a folder to create
creates the folder
cd to it
shows current dir
returning 1,2,3,4 in case of error, 0 in case of success
So you can see some C code to cd, pwd and mkdir
int main(void)
{
char asw[30];
char buffer[1024];
char* p = buffer;
const char* temp = "/tmp";
p = getcwd(p,1024);
printf("Current directory is: %s\n",p);
int n = chdir(temp);
if ( n != 0 ) return(1);
printf("directory changed to '%s'\n", temp);
printf("Enter name of directory to create: ");
fgets(asw,30,stdin);
asw[strlen(asw)-1] = 0;
n = mkdir(asw, 0777 );
if ( n != 0 ) return(2);
printf("'%s' created\n", buffer);
printf("Now changing to newly created folder\n");
sprintf(buffer,"%s/%s", temp, asw);
n = chdir(buffer);
if ( n != 0 ) return(4);
p = getcwd(p,1024);
printf("Current directory is: '%s'\n",p);
return 0;
Do not use system()

Capture Linux grep command to variable in C [duplicate]

I've got a utility that outputs a list of files required by a game. How can I run that utility within a C program and grab its output so I can act on it within the same program?
UPDATE: Good call on the lack of information. The utility spits out a series of strings, and this is supposed to be portable across Mac/Windows/Linux. Please note, I'm looking for a programmatic way to execute the utility and retain its output (which goes to stdout).
As others have pointed out, popen() is the most standard way. And since no answer provided an example using this method, here it goes:
#include <stdio.h>
#define BUFSIZE 128
int parse_output(void) {
char *cmd = "ls -l";
char buf[BUFSIZE];
FILE *fp;
if ((fp = popen(cmd, "r")) == NULL) {
printf("Error opening pipe!\n");
return -1;
}
while (fgets(buf, BUFSIZE, fp) != NULL) {
// Do whatever you want here...
printf("OUTPUT: %s", buf);
}
if (pclose(fp)) {
printf("Command not found or exited with error status\n");
return -1;
}
return 0;
}
Sample output:
OUTPUT: total 16
OUTPUT: -rwxr-xr-x 1 14077 14077 8832 Oct 19 04:32 a.out
OUTPUT: -rw-r--r-- 1 14077 14077 1549 Oct 19 04:32 main.c
For simple problems in Unix-ish environments try popen().
From the man page:
The popen() function opens a process by creating a pipe, forking and invoking the shell.
If you use the read mode this is exactly what you asked for. I don't know if it is implemented in Windows.
For more complicated problems you want to look up inter-process communication.
popen is supported on Windows, see here:
http://msdn.microsoft.com/en-us/library/96ayss4b.aspx
If you want it to be cross-platform, popen is the way to go.
Well, assuming you're on a command line in a windows environment, you can use pipes or command line redirects. For instance,
commandThatOutputs.exe > someFileToStoreResults.txt
or
commandThatOutputs.exe | yourProgramToProcessInput.exe
Within your program, you could use the C standard input functions to read the other programs output (scanf, etc.): http://irc.essex.ac.uk/www.iota-six.co.uk/c/c1_standard_input_and_output.asp . You could also use the file example and use fscanf. This should also work in Unix/Linux.
This is a very generic question, you may want to include more details, like what type of output it is (just text, or a binary file?) and how you want to process it.
Edit: Hooray clarification!
Redirecting STDOUT looks to be troublesome, I've had to do it in .NET, and it gave me all sorts of headaches. It looks like the proper C way is to spawn a child process, get a file pointer, and all of a sudden my head hurts.
So heres a hack that uses temporary files. It's simple, but it should work. This will work well if speed isn't an issue (hitting the disk is slow), or if it's throw-away. If you're building an enterprise program, looking into the STDOUT redirection is probably best, using what other people recommended.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
FILE * fptr; // file holder
char c; // char buffer
system("dir >> temp.txt"); // call dir and put it's contents in a temp using redirects.
fptr = fopen("temp.txt", "r"); // open said file for reading.
// oh, and check for fptr being NULL.
while(1){
c = fgetc(fptr);
if(c!= EOF)
printf("%c", c); // do what you need to.
else
break; // exit when you hit the end of the file.
}
fclose(fptr); // don't call this is fptr is NULL.
remove("temp.txt"); // clean up
getchar(); // stop so I can see if it worked.
}
Make sure to check your file permissions: right now this will simply throw the file in the same directory as an exe. You might want to look into using /tmp in nix, or C:\Users\username\Local Settings\Temp in Vista, or C:\Documents and Settings\username\Local Settings\Temp in 2K/XP. I think the /tmp will work in OSX, but I've never used one.
In Linux and OS X, popen() really is your best bet, as dmckee pointed out, since both OSs support that call. In Windows, this should help: http://msdn.microsoft.com/en-us/library/ms682499.aspx
MSDN documentation says
If used in a Windows program, the _popen function returns an invalid file pointer that causes the program to stop responding indefinitely. _popen works properly in a console application. To create a Windows application that redirects input and output, see Creating a Child Process with Redirected Input and Output in the Windows SDK.
You can use system() as in:
system("ls song > song.txt");
where ls is the command name for listing the contents of the folder song and song is a folder in the current directory. Resulting file song.txt will be created in the current directory.
//execute external process and read exactly binary or text output
//can read image from Zip file for example
string run(const char* cmd){
FILE* pipe = popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[262144];
string data;
string result;
int dist=0;
int size;
//TIME_START
while(!feof(pipe)) {
size=(int)fread(buffer,1,262144, pipe); //cout<<buffer<<" size="<<size<<endl;
data.resize(data.size()+size);
memcpy(&data[dist],buffer,size);
dist+=size;
}
//TIME_PRINT_
pclose(pipe);
return data;
}

How to write to a file in SD Card if one is inserted? [duplicate]

I've got a utility that outputs a list of files required by a game. How can I run that utility within a C program and grab its output so I can act on it within the same program?
UPDATE: Good call on the lack of information. The utility spits out a series of strings, and this is supposed to be portable across Mac/Windows/Linux. Please note, I'm looking for a programmatic way to execute the utility and retain its output (which goes to stdout).
As others have pointed out, popen() is the most standard way. And since no answer provided an example using this method, here it goes:
#include <stdio.h>
#define BUFSIZE 128
int parse_output(void) {
char *cmd = "ls -l";
char buf[BUFSIZE];
FILE *fp;
if ((fp = popen(cmd, "r")) == NULL) {
printf("Error opening pipe!\n");
return -1;
}
while (fgets(buf, BUFSIZE, fp) != NULL) {
// Do whatever you want here...
printf("OUTPUT: %s", buf);
}
if (pclose(fp)) {
printf("Command not found or exited with error status\n");
return -1;
}
return 0;
}
Sample output:
OUTPUT: total 16
OUTPUT: -rwxr-xr-x 1 14077 14077 8832 Oct 19 04:32 a.out
OUTPUT: -rw-r--r-- 1 14077 14077 1549 Oct 19 04:32 main.c
For simple problems in Unix-ish environments try popen().
From the man page:
The popen() function opens a process by creating a pipe, forking and invoking the shell.
If you use the read mode this is exactly what you asked for. I don't know if it is implemented in Windows.
For more complicated problems you want to look up inter-process communication.
popen is supported on Windows, see here:
http://msdn.microsoft.com/en-us/library/96ayss4b.aspx
If you want it to be cross-platform, popen is the way to go.
Well, assuming you're on a command line in a windows environment, you can use pipes or command line redirects. For instance,
commandThatOutputs.exe > someFileToStoreResults.txt
or
commandThatOutputs.exe | yourProgramToProcessInput.exe
Within your program, you could use the C standard input functions to read the other programs output (scanf, etc.): http://irc.essex.ac.uk/www.iota-six.co.uk/c/c1_standard_input_and_output.asp . You could also use the file example and use fscanf. This should also work in Unix/Linux.
This is a very generic question, you may want to include more details, like what type of output it is (just text, or a binary file?) and how you want to process it.
Edit: Hooray clarification!
Redirecting STDOUT looks to be troublesome, I've had to do it in .NET, and it gave me all sorts of headaches. It looks like the proper C way is to spawn a child process, get a file pointer, and all of a sudden my head hurts.
So heres a hack that uses temporary files. It's simple, but it should work. This will work well if speed isn't an issue (hitting the disk is slow), or if it's throw-away. If you're building an enterprise program, looking into the STDOUT redirection is probably best, using what other people recommended.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
FILE * fptr; // file holder
char c; // char buffer
system("dir >> temp.txt"); // call dir and put it's contents in a temp using redirects.
fptr = fopen("temp.txt", "r"); // open said file for reading.
// oh, and check for fptr being NULL.
while(1){
c = fgetc(fptr);
if(c!= EOF)
printf("%c", c); // do what you need to.
else
break; // exit when you hit the end of the file.
}
fclose(fptr); // don't call this is fptr is NULL.
remove("temp.txt"); // clean up
getchar(); // stop so I can see if it worked.
}
Make sure to check your file permissions: right now this will simply throw the file in the same directory as an exe. You might want to look into using /tmp in nix, or C:\Users\username\Local Settings\Temp in Vista, or C:\Documents and Settings\username\Local Settings\Temp in 2K/XP. I think the /tmp will work in OSX, but I've never used one.
In Linux and OS X, popen() really is your best bet, as dmckee pointed out, since both OSs support that call. In Windows, this should help: http://msdn.microsoft.com/en-us/library/ms682499.aspx
MSDN documentation says
If used in a Windows program, the _popen function returns an invalid file pointer that causes the program to stop responding indefinitely. _popen works properly in a console application. To create a Windows application that redirects input and output, see Creating a Child Process with Redirected Input and Output in the Windows SDK.
You can use system() as in:
system("ls song > song.txt");
where ls is the command name for listing the contents of the folder song and song is a folder in the current directory. Resulting file song.txt will be created in the current directory.
//execute external process and read exactly binary or text output
//can read image from Zip file for example
string run(const char* cmd){
FILE* pipe = popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[262144];
string data;
string result;
int dist=0;
int size;
//TIME_START
while(!feof(pipe)) {
size=(int)fread(buffer,1,262144, pipe); //cout<<buffer<<" size="<<size<<endl;
data.resize(data.size()+size);
memcpy(&data[dist],buffer,size);
dist+=size;
}
//TIME_PRINT_
pclose(pipe);
return data;
}

C Program - How to get the output of a shell command and compare it with a variable? [duplicate]

I've got a utility that outputs a list of files required by a game. How can I run that utility within a C program and grab its output so I can act on it within the same program?
UPDATE: Good call on the lack of information. The utility spits out a series of strings, and this is supposed to be portable across Mac/Windows/Linux. Please note, I'm looking for a programmatic way to execute the utility and retain its output (which goes to stdout).
As others have pointed out, popen() is the most standard way. And since no answer provided an example using this method, here it goes:
#include <stdio.h>
#define BUFSIZE 128
int parse_output(void) {
char *cmd = "ls -l";
char buf[BUFSIZE];
FILE *fp;
if ((fp = popen(cmd, "r")) == NULL) {
printf("Error opening pipe!\n");
return -1;
}
while (fgets(buf, BUFSIZE, fp) != NULL) {
// Do whatever you want here...
printf("OUTPUT: %s", buf);
}
if (pclose(fp)) {
printf("Command not found or exited with error status\n");
return -1;
}
return 0;
}
Sample output:
OUTPUT: total 16
OUTPUT: -rwxr-xr-x 1 14077 14077 8832 Oct 19 04:32 a.out
OUTPUT: -rw-r--r-- 1 14077 14077 1549 Oct 19 04:32 main.c
For simple problems in Unix-ish environments try popen().
From the man page:
The popen() function opens a process by creating a pipe, forking and invoking the shell.
If you use the read mode this is exactly what you asked for. I don't know if it is implemented in Windows.
For more complicated problems you want to look up inter-process communication.
popen is supported on Windows, see here:
http://msdn.microsoft.com/en-us/library/96ayss4b.aspx
If you want it to be cross-platform, popen is the way to go.
Well, assuming you're on a command line in a windows environment, you can use pipes or command line redirects. For instance,
commandThatOutputs.exe > someFileToStoreResults.txt
or
commandThatOutputs.exe | yourProgramToProcessInput.exe
Within your program, you could use the C standard input functions to read the other programs output (scanf, etc.): http://irc.essex.ac.uk/www.iota-six.co.uk/c/c1_standard_input_and_output.asp . You could also use the file example and use fscanf. This should also work in Unix/Linux.
This is a very generic question, you may want to include more details, like what type of output it is (just text, or a binary file?) and how you want to process it.
Edit: Hooray clarification!
Redirecting STDOUT looks to be troublesome, I've had to do it in .NET, and it gave me all sorts of headaches. It looks like the proper C way is to spawn a child process, get a file pointer, and all of a sudden my head hurts.
So heres a hack that uses temporary files. It's simple, but it should work. This will work well if speed isn't an issue (hitting the disk is slow), or if it's throw-away. If you're building an enterprise program, looking into the STDOUT redirection is probably best, using what other people recommended.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
FILE * fptr; // file holder
char c; // char buffer
system("dir >> temp.txt"); // call dir and put it's contents in a temp using redirects.
fptr = fopen("temp.txt", "r"); // open said file for reading.
// oh, and check for fptr being NULL.
while(1){
c = fgetc(fptr);
if(c!= EOF)
printf("%c", c); // do what you need to.
else
break; // exit when you hit the end of the file.
}
fclose(fptr); // don't call this is fptr is NULL.
remove("temp.txt"); // clean up
getchar(); // stop so I can see if it worked.
}
Make sure to check your file permissions: right now this will simply throw the file in the same directory as an exe. You might want to look into using /tmp in nix, or C:\Users\username\Local Settings\Temp in Vista, or C:\Documents and Settings\username\Local Settings\Temp in 2K/XP. I think the /tmp will work in OSX, but I've never used one.
In Linux and OS X, popen() really is your best bet, as dmckee pointed out, since both OSs support that call. In Windows, this should help: http://msdn.microsoft.com/en-us/library/ms682499.aspx
MSDN documentation says
If used in a Windows program, the _popen function returns an invalid file pointer that causes the program to stop responding indefinitely. _popen works properly in a console application. To create a Windows application that redirects input and output, see Creating a Child Process with Redirected Input and Output in the Windows SDK.
You can use system() as in:
system("ls song > song.txt");
where ls is the command name for listing the contents of the folder song and song is a folder in the current directory. Resulting file song.txt will be created in the current directory.
//execute external process and read exactly binary or text output
//can read image from Zip file for example
string run(const char* cmd){
FILE* pipe = popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[262144];
string data;
string result;
int dist=0;
int size;
//TIME_START
while(!feof(pipe)) {
size=(int)fread(buffer,1,262144, pipe); //cout<<buffer<<" size="<<size<<endl;
data.resize(data.size()+size);
memcpy(&data[dist],buffer,size);
dist+=size;
}
//TIME_PRINT_
pclose(pipe);
return data;
}

Not able to read data in from a text file.

Im having a problem finding out where to store my Text File which I want to read from. I stored it in the same directory as the executable file but it is still not reading the file in. After much digging and searching I have found that the problem has something to do with the "Derived Data" in Xcode. When I look for the source file , by right clicking on the main.c file and locating the file in finder I find that it is located within the Derived Data. Whenever I run this program it creates some derived data (which Xcode is supposed to do) but my .c file is stored within this derived data and when I try and store the text file in the same location the executable is located (the same place the .c file is located) I am not able to read in the file.
Suggestions?
Ideas?
Help..
#include <stdio.h>
#include <unistd.h>
extern int errno;
int main (void){
int term;
long long StudentID;
char lastname [16];
char firstname[16];
char subject[4];
int catalog;
char section[4];
char filename [9];
FILE *cfPtr;
printf("Enter file name: ");
scanf("%s",filename);
/*
char cwd [1024];
if (getcwd(cwd, sizeof(cwd)) != NULL)
fprintf(stdout, "Current working dir: %s\n", cwd);
*/
system("pwd");
if((cfPtr=fopen(filename,"r"))==0){
//printf("%s jlk",strerror(errno));
printf("File could not be opened\n");
}
else{
printf("%-35s%-10s%-10s%-10s%-10s\n","Last Name, First Name","Term","ID","Course","Section");
int i;
for(i=0; i<75; i++){
printf("-");
}
fscanf(cfPtr,"%d%lld%s%s%s%d%s",&term,&StudentID,lastname,firstname,subject,&catalog,section);
while(!feof(cfPtr)){
printf("%-35s%-10s%d%lld%-10s%-10s\n", lastname, firstname,term,StudentID,subject,section);
fscanf(cfPtr,"%d%lld%s%s%s%d%s",&term,&StudentID,lastname,firstname,subject,&catalog,section);
}
fclose(cfPtr);
}
return 0;
}
If you've set up a "Command Line Tool" project in Xcode, then you can set the working directory as follows. First click on the project name at the top of the Xcode window and select "Edit Scheme..."
Then select "Run Debug" on the left and change the "Working Directory" on the right.
The alternative is to download the command line tools (Preferences/Downloads). Then you can open a terminal window, and compile/run from the command line.

Resources