I have suppose two text file abc.txt and def.txt in folder "my". I have a programme which directly goes to that folder and search particular file and if that particular file find out then how to access that file's information.
I know how to read write file in C through file handling but I have no idea how to search particular file and after that read that particular file to match particular string in file.
**All these things access through file handling in C.**
So please if any one have any solution I will be thankful for that
Example will be best way to understand .
Thanks in advance
To get a listing of the files in a directory in Linux, you can use the 'opendir', 'readdir' and 'closedir' functions from 'dirent.h'. For example:
#include <dirent.h>
#include <stdio.h>
int ListDir(const char *pDirName)
{
DIR *pDir;
struct dirent *pEntry;
pDir = opendir(pDirName);
if (!pDir)
{
perror("opendir");
return -1;
}
while ((pEntry = readdir(pDir)) != NULL)
{
printf("%s\n", pEntry->d_name);
}
closedir(pDir);
return 0;
}
Related
I was trying to make a program to copy files from the documents folder on my Linux machine into the documents folder onto a USB with Windows on it. So far, it only creates files without copying any actual data to them, but that's not the problem I'm trying to solve right now. The code looks like this (there are no real errors, more information is written under the code):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
int main()
{
DIR *folder;
struct dirent *entry;
int files = 0;
folder = opendir("/home/ubuntumate/Documents");
if(folder == NULL)
{
perror("Unable to read directory");
return(1);
}
while( (entry=readdir(folder)) )
{
if(entry->d_type == DT_REG)
{
files++;
char newfilename[100];
snprintf(newfilename, sizeof(newfilename), "/media/ubuntumate/7494348594344C3C/Users/John/Documents/%s", entry->d_name);
FILE *clone = fopen(newfilename, "w");
fclose(clone);
}
}
closedir(folder);
return(0);
}
You may have noticed that I hard-coded the media's location, including both the username and the media's id. (my username is "ubuntumate" because I'm on a virtual machine running Ubuntu MATE). The question I'm asking is how do i get a list of all the medias attached to the machine, so that this program can still work with a different user, and on a different USB that also contains windows?
You can check whether a block device is removable under the sys hierarchy. E.g. something like
$ stat /dev/sdc|grep Device
Device: 6h/6d Inode: 347 Links: 1 Device type: 8,20
From here you see the device is major number 8, minor 20 (in hex). Then check
$ cat /sys/dev/block/8\:32/removable
0
Never mind, I found an answer. I can just list all the folders in the media/[username] folder. There are a lot of tutorials on getting the username so that one wont be a problem, cuz i can just search it up.
I found the answer to another question here to be very helpful.
There seems to be a limitation of the sys/stat.h library as when I tried to look in other directories everything was seen as a directory.
I was wondering if anyone knew of another system function or why it sees anything outside the current working directory as only a directory.
I appreciate any help anyone has to offer as this is perplexing me and various searches have turned up no help.
The code I made to test this is:
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
int main(void) {
int status;
struct stat st_buf;
struct dirent *dirInfo;
DIR *selDir;
selDir = opendir("../");
// ^ or wherever you want to look
while ((dirInfo = readdir(selDir))) {
status = stat (dirInfo->d_name, &st_buf);
if (S_ISREG (st_buf.st_mode)) {
printf ("%s is a regular file.\n", dirInfo->d_name);
}
if (S_ISDIR (st_buf.st_mode)) {
printf ("%s is a directory.\n", dirInfo->d_name);
}
}
return 0;
}
You need to check the status of the stat call; it is failing.
The trouble is that you're looking for a file the_file in the current directory when it is actually only found in ../the_file. The readdir() function gives you the name relative to the other directory, but stat() works w.r.t the current directory.
To make it work, you'd have to do the equivalent of:
char fullname[1024];
snprintf(fullname, sizeof(fullname), "%s/%s", "..", dirInfo->d_name);
if (stat(fullname, &st_buf) == 0)
...report on success...
else
...report on failure...
If you printed out stat, you'll notice there's an error (File not found).
This is because stat takes the path to the file, but you're just providing the file name.
You then call IS_REG on garbage values.
So, suppose you have a file ../test.txt
You call stat on test.txt...That isn't in directory ./test.txt, but you still print out the results from IS_REG.
My first post :), am starting out with C language as basic learning step into programming arena. I am using following code which reads string from text file, makes directory with that string name and opens a file for writing in that created directory. But am not able to create a file inside directory made, here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
#include <string.h>
int main()
{
char file_name[25], cwd[100];
FILE *fp, *op;
fp = fopen("myfile.txt", "r");
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
fgets(file_name, 25, fp);
_mkdir(file_name);
if (_getcwd(cwd,sizeof(cwd)) != 0)
{
fprintf(stdout, "Your dir name: %s\\%s\n", cwd,file_name);
op = fopen("cwd\\file_name\\mynewfile.txt","w");
fclose(op);
}
fclose(fp);
return 0;
}
What you need is to store the file name (with the path) in a c-string before opening. What you are opening is cwd\file_name\mynewfile.txt. I doubt that your directory is named cwd.
A sample could could be:
char file_path[150];
sprintf(file_path, "%s\\%s\\mynewfile.txt", cwd, file_name);
op = fopen(file_path,"w");
use
#include <sys/stat.h>
#include <sys/types.h>
instead of
#include <direct.h>
and modify
op = fopen("cwd\\file_name\\mynewfile.txt","w”);
I see you are using the return values. That is a good start for a beginner. You can refine your error messages by including "errno.h". Instead of printing your own error messages call
printf("%s", strerror(errno));
You get more precise error messages that way.
op = fopen("cwd\\file_name\\mynewfile.txt","w”);
You’re actually passing the string literals “cwd” and “file_name” as part of the path of the file, when I think you actually mean to put the contents of the variables with those names in there. You will probably have to piece together a string for the path. Try looking into strcat()
http://www.cplusplus.com/reference/cstring/strcat/
What is the correct way to read and extract data from text files when you know that there will be many in a directory? I know that you can use fopen() to get the pointer to the file, and then do something like while(fgets(..) != null){} to read from the entire file, but then how could I read from another file? I want to loop through every file in the directory.
Sam, you can use opendir/readdir as in the following little function.
#include <stdio.h>
#include <dirent.h>
static void scan_dir(const char *dir)
{
struct dirent * entry;
DIR *d = opendir( dir );
if (d == 0) {
perror("opendir");
return;
}
while ((entry = readdir(d)) != 0) {
printf("%s\n", entry->d_name);
//read your file here
}
closedir(d);
}
int main(int argc, char ** argv)
{
scan_dir(argv[1]);
return 0;
}
This just opens a directory named on the command line and prints the names of all files it contains. But instead of printing the names, you can process the files as you like...
Typically a list of files is provided to your program on the command line, and thus are available in the array of pointers passed as the second parameter to main(). i.e. the invoking shell is used to find all the files in the directory, and then your program just iterates through argv[] to open and process (and close) each one.
See p. 162 in "The C Programming Language", Kernighan and Ritchie, 2nd edition, for an almost complete template for the code you could use. Substitute your own processing for the filecopy() function in that example.
If you really need to read a directory (or directories) directly from your program, then you'll want to read up on the opendir(3) and related functions in libc. Some systems also offer a library function called ftw(3) or fts(3) that can be quite handy too.
I'm trying to create 5000 junk files, write them to a file and delete them. But this code only is writing a portion of the files to the file. ls -l | grep ^- | wc -l says I have 1598 files remaining in the directory that is supposed to be emptied with unlink();. If I remove close(fd) I get a seg fault if I do any more than 1000 files. Any suggestions?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
main (int argv, char *args[]){
if(argv<3){
printf("Please run with proper command line arguements.\n");
return;
}
int numFiles = atoi(args[1]);
char *fileName = args[2];
char *fileList[numFiles];
int x, ret,fd;
char buff[50];
for(x=0;x<numFiles;x++){
ret = sprintf(buff,"./stuff/%s-%d.junk",fileName, x);
fd = creat(buff);
close(fd);
}
DIR *odir = opendir("./stuff");
struct dirent *rdir = NULL;
FILE *fp;
fp = fopen("./files.list", "w");
x=0;
while(rdir = readdir(odir)){
char* name = rdir->d_name;
ret = sprintf(buff,"./stuff/%s-%d.junk",fileName, x);
if(strcmp(name,"..")!=0){
if(strcmp(name,".")!=0){
fprintf(fp,"%s %d\n",name,x);
x++;
}
}
unlink(buff);
}
close(fp);
closedir(odir);
}
Thanks!
Note: Use of creat(), opendir(), readdir() and unlink() were required for the assignment. And as for error checking, your right of course but I'm under time constraints and the TA really, really doesn't care... But thank you all!
Here you're using fopen:
FILE *fp;
fp = fopen("./files.list", "w");
But then you're using close instead of fclose to close it:
close(fp);
I'm not at all sure this is what's causing the problem you're seeing, but it's definitely wrong anyway. You probably just want unlink(rdir->d_name) instead of unlink(buff). You embedded the number into the file name when you created it -- you don't need to do it again when you're reading in the name of the file you created.
You're removing things from the directory while calling readdir; I think that's supposed to work OK, but you might want to consider avoiding it.
More to the point: as you iterate over the directory with readdir you're potentially removing different files from the ones readdir is listing. (Because what you pass to unlink is buff which you've filled in from the steadily-incrementing x rather than from anything returned by readdir.) So, here's a toy example to show why that's problematic. Suppose the directory contains files 1,2,3,4 and readdir lists them in the order 4,3,2,1.
readdir tells you about file 4. You delete file 1.
readdir tells you about file 3. You delete file 2.
readdir would have told you about file 2, but it's gone so it doesn't.
readdir would have told you about file 1, but it's gone so it doesn't.
You end up with files 3 and 4 still in the directory.