NULL memories entry - c

I wrote this little program that reads a file in binary form (Databases.db in this example) and copies its content in the cpydatabases.db...
When I run the debugger in the fopen_s(&source, "Databases.db", "r");, the source is always NULL (while debugging it shows that the memory entry is always Null, 0x000000000000 <NULL>).
This program runs in visual studio 2015.
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include "dirent.h"
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#define BUFFSIZE 2048
char ch, *readbuf;
int nread, nwrit;
FILE *source, *target;
int main()
{
int returnv;
fopen_s(&source, "Databases.db", "r");
if ( source !== NULL)
{
fclose(source);
return (EXIT_FAILURE);
}
fopen_s(&target,"cpydatabases.db", "w");
//check again
if (target == NULL)
{
fclose(target);
return(EXIT_FAILURE);
}
//setting the char that reads the binary
readbuf = (char *)malloc(BUFFSIZE* sizeof(char));
if (readbuf == NULL)
{
fclose(source);
fclose(target);
return(EXIT_FAILURE);
}
while (1)
{
nread = fread((void *)readbuf, sizeof(char), BUFFSIZE, source) ;
// fwrite((void *)readbuf, sizeof(char), nread, target);
nwrit = fwrite((void *)readbuf, sizeof(char), nread, target);
if (nwrit < nread)
{
returnv = (EXIT_FAILURE);
}
if (nread <= BUFFSIZE)
{
returnv = (EXIT_SUCCESS);
break;
}
}
fclose(source);
fclose(target);
return 0;
}

This worked for me. You should have your Databases.db file in the same folder as your source.cpp file, or use an absolute path like "C:/Databases". Anyway this code worked for me:
#define BUFFSIZE 2048
char ch, source_file[50], target_file[50], *readbuf;
int nread, nwrit;
FILE *source, *target;
int main()
{
int returnv;
fopen_s(&source, "Databases.db", "r");
if (source == NULL)
{
//fclose(source);
return (EXIT_FAILURE);
}
fopen_s(&target, "cpydatabases.db", "w");
//check again
if (target == NULL)
{
fclose(target);
return(EXIT_FAILURE);
}

I think "Databases.db" is in not in same directory where executable is.
You can give complete path of "Databases.db" or copy this file where your .sln file is.

Related

How to add buffering while using getc and putc

I want to make copy/paste with using c FILE but i need to add read/write buffer too and I am not sure how to add it. Is there any function similar to regular read/write..Code is below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[]) {
FILE* fsource, * fdestination;
printf("enter the name of source file:\n");
char sourceName[20], destinationName[20];
strcpy(sourceName, argv[1]);
strcpy(destinationName, argv[2]);
fsource = fopen(sourceName, "r");
if (fsource == NULL)
printf("read file did not open\n");
else
printf("read file opened sucessfully!\n");
fdestination = fopen(destinationName, "w");
if (fdestination == NULL)
printf("write file did not open\n");
else
printf("write file opened sucessfully!\n");
char pen = fgets(fsource);
while (pen != EOF)
{
fputc(pen, fdestination);
pen = fgets(fsource);
}
fclose(fsource);
fclose(fdestination);
return 0;
}
Here's a reworking of your code (sans some error handling) that reads and writes in 256-byte increments:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *sourceName = argv[0];
char destName[256];
snprintf(destName, 256, "%s.copy", sourceName);
printf("Copying %s -> %s\n", sourceName, destName);
FILE *fsource = fopen(sourceName, "rb");
FILE *fdest = fopen(destName, "w");
char buffer[256];
for (;;) {
size_t bytesRead = fread(buffer, 1, 256, fsource);
if (bytesRead == 0) {
break;
}
if (fwrite(buffer, 1, bytesRead, fdest) != bytesRead) {
printf("Failed to write all bytes!");
break;
}
printf("Wrote %ld bytes, position now %ld\n", bytesRead, ftell(fdest));
}
fclose(fsource);
fclose(fdest);
return 0;
}
The output is e.g.
$ ./so64481514
Copying ./so64481514 -> ./so64481514.copy
Wrote 256 bytes, position now 256
Wrote 256 bytes, position now 512
Wrote 256 bytes, position now 768
Wrote 256 bytes, position now 1024
[...]
Wrote 168 bytes, position now 12968

fopen: file does not exist but it does

I want to read all files that I can find in the folder where my executable is, except the runnable file that I'm running. I code the following code but, although this list correctly the files that I have in my folder, I cannot open them with fopen because fopen prints that the file doesn't exists. If I do gedit "path of the file obtained from my program in c" then it opens perfectly from the term. Where is the bug?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
int main (int argc, char **argv) {
//Determining the number of files we have.
//We call to a bash command http://stackoverflow.com/questions/646241/c-run-a-system-command-and-get-output
FILE *fp, *fin;
char path[1035], cwd[1024];
int scanned = 0;
/* Open the command for reading. */
//https://askubuntu.com/questions/370697/how-to-count-number-of-files-in-a-directory-but-not-recursively
//This count soft and hard links also (I think)
fp = popen("ls -F |grep -v /", "r");
if (fp == NULL) {
printf("Failed to run command\n" );
exit(1);
}
/* Read the output a line at a time - output it. */
//Loop for each file. Be careful! if the exe is inside, it will also be counted!
while (fgets(path, sizeof(path)-1, fp) != NULL) {
printf("Reading file: %s\n", path);
fin=fopen(path,"r");
scanned = 0;
printf("caa");
if (fin != NULL){
printf("AA\n");
fclose(fin);
}
if (!fin)perror("fopen");
printf("Done! \n");
}
/* close */
pclose(fp);
printf("end");
return 0;
}
There are 2 bugs in your code:
when the code updates the "path" variable in your code. It has a newline at the end which needs to be corrected to NUL. This gives an incorrect path.
Something like below can be appended to your code:
while (fgets(path, sizeof(path)-1, fp) != NULL) {
len=strlen(path);
path[len-1]='\0';
Use 'ls -A1', since 'ls -F' adds a '*' in binary name:
fp = popen("ls -A1 |grep -v /", "r");
ok so just in case someone else needs a better approach, I redid the code with the comments I had. Here I let you the new code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
int isDirectory(const char *path) {
struct stat statbuf;
if (stat(path, &statbuf) != 0)
return 0;
return S_ISDIR(statbuf.st_mode);
}
int main (int argc, char **argv) {
FILE *fp, *fin;
char path[1035], cwd[1024];
int scanned = 0;
int ints;
DIR *dir;
struct dirent *ent;
//getcwd prints directory where the app ran.
if ((dir = opendir (getcwd(cwd, sizeof(cwd)))) != NULL) {
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL) {
/*Skips . and ..*/
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) continue;
if (isDirectory(ent->d_name) != 0) continue;
printf ("Reading file: %s\n", ent->d_name);
scanned = 0;
fin=fopen(ent->d_name,"r");
if (fin != NULL){
while ((scanned = fscanf(fin, "%d", ints)) != EOF) {
if(scanned == 1){
printf("%d\n", ints);
}else {
printf("Whoops! Input format is incorrect!\n");
break;
}
} //LOOP: reading file
fclose(fin);
}
if (!fin)perror("fopen");
printf("Done! \n");
}//LOOP: while opendir
closedir (dir);
} else {
/* could not open directory */
perror ("opendir");
return EXIT_FAILURE;
}
return 0;
}

Opening a file using relative path

The following code is supposed to work as follows: print the list of the files in a directory, and print the content of each .c file.
it works fine when executed in UNIX for the same directory: ./a.out ./
However, I was not able to make it work for ./a.out ../differentDir execution.
I know that if the absolute path is provided as an argument, I could use argv[1] for that. However, when it is provided in a form of a relative path I am lost.
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFFSIZE 32768
int main(int argc, char **argv) {
char buf[BUFFSIZE];
DIR *dp;
struct dirent *dirp;
char filename[80];
int name_length;
FILE *fp;
if (argc != 2) {
fprintf(stderr, "usage: %s dir_name\n", argv[0]);
exit(1);
}
if ((dp = opendir(argv[1])) == NULL ) {
fprintf(stderr, "can't open '%s'\n", argv[1]);
exit(1);
}
while ((dirp = readdir(dp)) != NULL ){
printf("%s\n", dirp->d_name);
memset(filename, '\0', sizeof(filename));
strcpy(filename, dirp->d_name);
printf(" ** %s ", filename);
name_length = strlen(filename);
printf(" name_length=%d \n", name_length);
if (findC(filename)) // checking if the file has a .c extension
{
fp=fopen(filename, "r");
if (fp == NULL)
fprintf(stderr, "Can't open .C file!\n");
else
{// if the file was opened successfuly:
do
{
fgets(buf,BUFFSIZE,fp); // reading each line until buffer is full or until reaching whitespace
buf[strlen(buf)-1]='\0'; // removing the trailing whitespace from the buffer
puts(buf);
}
while (!feof(fp));
printf("\n\n");
fclose(fp);
}
}
}
closedir(dp);
return(0);
}
/*FindC method gets a c-string that represents a file name; returns 1 if the file ends with .C extension, else returns 0*/
int findC(char * name)
{
int len = strlen(name);
if (len>=2 && name[len-2]=='.' && tolower(name[len-1])=='c')
return 1;
return 0;
}
Upon opening the file to read, the file pathname needs to also be relative.
// Form prefix for complete relative file name
char filename[MAXPATH];
strcpy(filename, argv[1]);
// append '/' if directory path does not end in '/'
if (TBD_code(filename)) {
strcat(filename, "/");
}
char *end = filename[strlen(filename)];
while ((dirp = readdir(dp)) != NULL ){
printf("%s\n", dirp->d_name);
if (findC(dirp->d_name)) {
// append filename to prefix
strcpy(end, dirp->d_name);
fp=fopen(filename, "r");
...
You can use realpath(argv1...) like in this example. realpath will return the absolute path for a relative path.
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
int main(int argc, char **argv) {
char *path = "../..";
char buff[PATH_MAX + 1]; /* not sure about the "+ 1" */
char *res = realpath(path, buff);
if (res) {
printf("This source is at %s.\n", buff);
} else {
perror("realpath");
exit(EXIT_FAILURE);
}
return 0;
}
To include the desired behavior in your program, you can use realpathin your code:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
#include <dirent.h>
#include <string.h>
#define BUFFSIZE 32768
int main(int argc, char **argv) {
char buf[BUFFSIZE];
DIR *dp;
struct dirent *dirp;
char filename[80];
int name_length;
FILE *fp;
char buff[PATH_MAX + 1]; /* not sure about the "+ 1" */
if (argc != 2) {
fprintf(stderr, "usage: %s dir_name\n", argv[0]);
exit(1);
}
char *res = realpath(argv[1], buff);
if ((dp = opendir(res)) == NULL ) {
fprintf(stderr, "can't open '%s'\n", argv[1]);
exit(1);
}
while ((dirp = readdir(dp)) != NULL ){
printf("%s\n", dirp->d_name);
memset(filename, '\0', sizeof(filename));
strcpy(filename, dirp->d_name);
printf(" ** %s ", filename);
name_length = strlen(filename);
printf(" name_length=%d \n", name_length);
if (findC(filename)) // checking if the file has a .c extension
{
fp=fopen(filename, "r");
if (fp == NULL)
fprintf(stderr, "Can't open .C file!\n");
else
{// if the file was opened successfuly:
do
{
fgets(buf,BUFFSIZE,fp); // reading each line until buffer is full or until reaching whitespace
buf[strlen(buf)-1]='\0'; // removing the trailing whitespace from the buffer
puts(buf);
}
while (!feof(fp));
printf("\n\n");
fclose(fp);
}
}
}
closedir(dp);
return(0);
}
/*FindC method gets a c-string that represents a file name; returns 1 if the file ends with .C extension, else returns 0*/
int findC(char * name)
{
int len = strlen(name);
if (len>=2 && name[len-2]=='.' && tolower(name[len-1])=='c')
return 1;
return 0;
}
You could first change to the directory chdir either with relative or absolute path and the get the absolute path via the getcwd
#include <sys/types.h>
#include <string.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFFSIZE 32768
#define PATH_SIZE 512
int main(int argc, char **argv) {
char buf[BUFFSIZE];
char path[PATH_SIZE];
DIR *dp;
struct dirent *dirp;
char filename[80];
int name_length, r;
FILE *fp;
if (argc != 2) {
fprintf(stderr, "usage: %s dir_name\n", argv[0]);
exit(1);
}
strcpy(path, argv[1]);
r = chdir(path);
if( r != 0 )
{
printf("Invalid path '%s'\n",path);
exit(1);
}
getcwd(path,PATH_SIZE);
if ((dp = opendir(path)) == NULL ) {
fprintf(stderr, "can't open '%s'\n", argv[1]);
exit(1);
}
while ((dirp = readdir(dp)) != NULL ){
printf("%s\n", dirp->d_name);
memset(filename, '\0', sizeof(filename));
strcpy(filename, dirp->d_name);
printf(" ** %s ", filename);
name_length = strlen(filename);
printf(" name_length=%d \n", name_length);
if (findC(filename)) // checking if the file has a .c extension
{
fp=fopen(filename, "r");
if (fp == NULL)
fprintf(stderr, "Can't open .C file!\n");
else
{// if the file was opened successfuly:
do
{
fgets(buf,BUFFSIZE,fp); // reading each line until buffer is full or until reaching whitespace
buf[strlen(buf)-1]='\0'; // removing the trailing whitespace from the buffer
puts(buf);
}
while (!feof(fp));
printf("\n\n");
fclose(fp);
}
}
}
closedir(dp);
return(0);
}
/*FindC method gets a c-string that represents a file name; returns 1 if the file ends with .C extension, else returns 0*/
int findC(char * name)
{
int len = strlen(name);
if (len>=2 && name[len-2]=='.' && tolower(name[len-1])=='c')
return 1;
return 0;
}

Error validating the contents of a file using regex in C

I am having a problem with the below code validating a file using regex. My file must only contain letters or numbers. My regular expression is:
#define to_find "^[a-zA-Z0-9]+$"
which is located in my main.h file. The below code is in my main.c
#include <ctype.h>
#include <errno.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "main.h"
int main(int argc, char * argv[])
{
int ret_val;
regex_t regex;
FILE *fp;
char line[1024];
if (regcomp(&regex, to_find, REG_EXTENDED) != 0)
{
fprintf(stderr, "Failed to compile regex '%s'\n", to_find);
return EXIT_FAILURE;
}
if (argc > 2)
{
printf("Usage: tree OR tree [filename]\n");
return EXIT_FAILURE;
}
else if (argc == 2)
{
fp = fopen(strcat(argv[1],".dat"), "r");
printf("file opened\n");
while ((fgets(line, 1024, fp)) != NULL)
{
line[strlen(line) - 1] = '\0';
if ((ret_val = regexec(&regex, line, 0, NULL, 0)) != 0);
{
printf("Error: %s\n", line);
return EXIT_FAILURE;
}
}
fclose(fp);
printf("File closed\n");
}
return 0;
}
My file I am reading is called names.dat and contains:
int
char
[
double
What is happening is it is kicking out at the very first line which it should kick out at the 3rd line. I am sure this is pretty simple to solve but it seems I have not figured it out. I would appreciate any help. Also, how do I deal with the
\n
character in the file? this file will have several lines. Thanks in advance.
You have some small errors but the one that cause the error is:
// Do you see this sweet little semicolon :P ----------------+
if ((ret_val = regexec(&regex, line, 0, NULL, 0)) != 0); // <+
{
printf("Error: %s\n", line);
return EXIT_FAILURE;
}
beside this line:
fp = fopen(strcat(argv[1],".dat"), "r");
You cannot add to argv, you need to create a new buffer to hold the data, create a buffer with PATH_MAX size add append the path to it. Here an improved version:
#include <ctype.h>
#include <errno.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <limits.h>
#define to_find "^[a-zA-Z0-9]+$"
int main(int argc, char * argv[])
{
int ret_val;
regex_t regex;
FILE *fp;
char file[PATH_MAX];
char line[1024];
if (regcomp(&regex, to_find, REG_EXTENDED) != 0)
{
fprintf(stderr, "Failed to compile regex '%s'\n", to_find);
return EXIT_FAILURE;
}
if (argc > 2)
{
printf("Usage: tree OR tree [filename]\n");
return EXIT_FAILURE;
}
else if (argc == 2)
{
sprintf(file, "%s.dat", argv[1]);
fp = fopen(file, "r");
if( fp == NULL ) {
perror("Error");
return -1;
}
printf("file opened\n");
while (fscanf(fp, "%1023s", line) > 0)
{
if ((ret_val = regexec(&regex, line, 0, NULL, 0)) != 0)
{
printf("Not match: %s\n", line);
//return EXIT_FAILURE;
} else {
printf("Match: %s\n", line);
}
}
regfree(&regex);
fclose(fp);
printf("File closed\n");
}
return 0;
}
See the diff: http://www.diffchecker.com/8itbz5dy
test:
$ gcc -Wall sample.c
$
$ cat name.dat
int
char
[
double
$ ./a.out name
file opened
Match: int
Match: char
Not match: [
Match: double
File closed
$

stat() returns error

I have to know the modification date of some files in a folder. It works, but not with all types of files.
For example it works with .c, .txt, but it doesn't work with other types such .mp4, .jpg and .mp3 (the application I'm creating have to work with multimedia files in general). It prints "Cannot display the time.", so I suppose the problem is on stat(). Thanks.
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
char parola[12]="", hash[32]="", esadecimale[1000]="", system3[100]="./md5 ";
int i, len, len2;
int bytes;
char cwd[1024];
int main(void)
{
char t[100] = "";
struct stat b;
DIR *dp;
char destinationFolder[100] = "/Users/mattiazeni/Desktop/Prova/"; //Me la passa da sopra
struct dirent *dir_p;
dp = opendir(destinationFolder);
if ( dp == NULL ) exit(1);
len = strlen(destinationFolder);
for (i=0;i<len;i++) {
system3[i+6]=destinationFolder[i];
}
while( ( dir_p = readdir(dp) ) != NULL ) {
if (dir_p -> d_name[0] != '.') {
//printf("%s\n", dir_p -> d_name);
len2 = strlen(dir_p -> d_name);
for (i=0;i<len2;i++) {
if (dir_p -> d_name[i] == ' '){ //Mi serve per correggere i nomi dei file con spazi
system3[i+len+6]='\\';
}
else system3[i+len+6]=dir_p -> d_name[i];
}
system(system3); //Passa il valore a md5 che calcola l'hash e lo stampa nel file che ci serve insieme al persorso/nome del file
FILE *fp;
if((fp=fopen("userDatabase.txt", "ab"))==NULL) {
printf("Error while opening the file..\n");
fclose (fp);
}
else {
if (!stat(dir_p -> d_name, &b)) {
strftime(t, 100, "%d/%m/%Y %H:%M:%S", localtime( &b.st_mtime)); //C'è ancora qualche errore!!
fprintf(fp, "%s", t);
}
else {
perror(0);
fprintf(fp, "error");
}
fprintf(fp, " initialized");
fprintf(fp, "\n");
}
fclose (fp);
for (i=len+6;i<len+6+len2;i++) {
system3[i]=' ';
}
}
}
closedir(dp);
return 0;
}
Use perror(). Also shouldn't you use st_mtime?
stat:
On success, zero is returned.
On error, -1 is returned, and errno is set appropriately.
99% sure it is because dir_p -> d_name does not exist, which in turn probably is because of a localization issue.
You could do something like:
fprintf(stderr,
"Unable to stat %s\n",
dir_p->d_name);
perror(0);
Also; shouldn't it be ->f_name and not ->d_name if you are checking file status? - (Unless you use d_name for file name off course.)
And your fclose(fp) is outside your fp == NULL check. As you do not return or otherwise abort the flow you risk an SIGSEGV if the fopen fail.
Edit: What do you get with something like this?
#include <unistd.h>
char cwd[1024];
...
} else {
fprintf(stderr,
"Unable to stat '%s'\n",
dir_p->d_name);
perror(0);
if (getcwd(cwd, sizeof(cwd)) == NULL) {
perror("getcwd() error");
} else {
fprintf(stderr,
"in directory '%s'\n",
cwd);
}
}
Edit2:
First; I said getcwd() != NULL should be ==. Se change. (Bad by me.)
The problem in your code. (There is a few more) but regarding stat - you use d_name from readdir. This is only filename; not dir+filename. Thus; you get i.e.:
stat(dir_p->d_name, ...)
Which becomes i.e.:
stat("file.mp4", ...)
Easiest quick-fix (tho dirty) would be:
/* you need to terminate the system string after your for loop */
system3[i + len + 6] = '\0';
system(system3);
if (!stat(system3 + 6, &b)) {
You should use the complete pathname for stat(). Stat does not know which directory you are interested in.
...
char bigbuff[PATH_MAX];
sprintf( bigbuff, "%s/%s", destinationFolder, dir_p->d_name);
rc = stat (bigbuff, &b);
...
This is the final working code in order to scan a directory for files, and print them on a txt output file with the modification date:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
char system3[6]="./md5 ";
int main(void)
{
char t[100] = "";
char bigbuff[200];
struct stat b;
char destinationFolder[100] = "/Users/mattiazeni/Desktop/Prova"; //Me la passa da sopra
DIR *dp;
struct dirent *dir_p;
dp = opendir(destinationFolder);
if ( dp == NULL ) exit(1);
while( ( dir_p = readdir(dp) ) != NULL ) {
if (dir_p -> d_name[0] != '.') {
sprintf( bigbuff, "%s%s/%s",system3, destinationFolder, dir_p->d_name);
system(bigbuff);
FILE *fp;
if((fp=fopen("userDatabase.txt", "ab"))==NULL) {
printf("Error while opening the file..\n");
fclose (fp);
}
else {
sprintf( bigbuff, "%s/%s", destinationFolder, dir_p->d_name);
if (!stat(bigbuff, &b)) {
strftime(t, 100, "%d/%m/%Y %H:%M:%S", localtime( &b.st_mtime)); //C'è ancora qualche errore!!
fprintf(fp, "%s", t);
}
else {
perror(0);
fprintf(fp, "error");
}
fprintf(fp, "\n");
}
fclose (fp);
}
}
closedir(dp);
return 0;
}
Thanks all for the help!

Resources