C - listing files contained in folder and all subfolders - c

I have a function that reads all files contained in a single input directory.
I wanted to make that function read not only files in "main" directory, but also ones contained in all subdirectories.
In order to do so, i wrote this code:
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
struct dirent *readdir(DIR *dirp);
char * percorso;
DIR *cartella;
struct dirent *elemento;
char * scrivi(char * a, char * b)
{
char *targetdir = malloc(2048);
strcpy(targetdir,a);
strcat(targetdir,"/");
strcat(targetdir,b);
printf("%s \n", targetdir);
return targetdir;
}
void scorriFolder(char* nome)
{
if ((cartella = opendir(nome)) == NULL)
perror("opendir() error");
else {
printf("contents of root: \n");
while ((elemento = readdir(cartella)) != NULL)
{
if(elemento->d_type == DT_DIR)
{
if(elemento->d_name != ".." || elemento->d_name != ".")
{
percorso = scrivi(nome, elemento->d_name);
scorriFolder(percorso);
}
}
else
{
printf(" %s\n", elemento->d_name);
}
}
closedir(cartella);
}
}
main(int argc, char * argv[]) {
scorriFolder(argv[1]);
}
But it doesn't even compile, saying:
warning: incompatible implicit declaration of built-in function ‘malloc’
warning: incompatible implicit declaration of built-in function ‘strcpy’
warning: incompatible implicit declaration of built-in function ‘strcat’
As far as I know, this issue is due to a wrong format of variables passed into malloc, strcpy and strcat functions. (elemento->d_name has type char and not char*
What can I do, in order to get this code work?
Thanks.
EDIT
This is a working while snippet:
while ((elemento = readdir(cartella)) != NULL)
{
if ( strcmp(elemento->d_name, ".") == 0)
{
continue;
}
if ( strcmp(elemento->d_name, "..") == 0)
{
continue;
}
if(elemento->d_type == DT_DIR)
{
{
percorso = scrivi(nome, elemento->d_name);
scorriFolder(percorso);
}
}
else
{
printf(" %s\n", elemento->d_name);
}
}
Once it scans a subdirectory it crashes because path it is not updated as the program exits from subdirectory. I am trying to fix it.

You need to add #include <stdlib.h> and #include <string.h> to the beginning of the file.
warning: incompatible implicit declaration of built-in function ‘malloc’
This error message is telling you that the compiler can't determine the return type and parameters to malloc. I think the compiler assumes int for the return type if it can't find one. Which is not void * which malloc actually returns.
malloc is defined in <stdlib.h>
strcpy and strcat are defined in <string.h>
To find out where these functions are defined you can read the man page by typing man malloc , man strcpy, or man strcat

Related

Compilation returning "Warning: assignment from incompatible pointer type"

Question
Hi, I've this function to check the current path and return the pointer of char with the path. But when I go to compile with GCC it return this two warnings. I've tried some solutions but I was can't fix it.
What is supposed to do about this warnings?
Warnings
In file included from C:\Users\Lsy\Documents\C\murtza_debug\main.c:10:0:
C:\Users\Lsy\Documents\C\murtza_debug\system/path.h:6:10: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
int *p = cwd;
^~~
C:\Users\Lsy\Documents\C\murtza_debug\system/path.h: In function 'get_path':
C:\Users\Lsy\Documents\C\murtza_debug\system/path.h:9:7: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
p = &cwd;
^
Code
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
char cwd[8024];
int *p = cwd;
int* get_path() {
p = &cwd;
if (getcwd(cwd, sizeof(cwd)) != NULL) {
return p;
}
}
cwd is an array of char and it is converted to a pointer char* to the first element of the array before being assigned. Therefore, you should use char*, not int*, as the type of p to have it accept that and use char* as return type of get_path() to return p.
Also &cwd is an another type of pointer char(*)[8024] (an pointer to the array itself). It should be cwd to use only one type of pointer.
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
char cwd[8024];
char *p = cwd;
char* get_path() {
p = cwd;
if (getcwd(cwd, sizeof(cwd)) != NULL) {
return p;
}
}

Trying to return two pointer to two dimensional Array in C

I'm very new to C and having trouble returned a pointer to a two dimensional array.
The purpose of the code is to go into a folder called rules. From this folder it finds all the file paths for all the files in the rule folder. I want to populate the a two dimensional array with the complete file paths. As of now my code is capable of populating a two dimensional array with the the filepaths (this is done in the listFiles Method). I would like to use this two dimensional array within the main method, to do some further stuff. But I am having issues trying to get it to return, without causing compiling issues.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#ifdef WINDOWS
#include <direct.h>
#define GetCurrentDir _getcwd
#else
#include <unistd.h>
#define GetCurrentDir getcwd
#endif
#include <string.h>
void listFiles(char *path);
int main() {
// Directory path to list files
char path[100];
char buff[FILENAME_MAX];
GetCurrentDir(buff, FILENAME_MAX);
// printf("%s\n",buff);
char toRuleFolder[100] = "/rules";
strcat(buff, toRuleFolder);
// printf("%s\n",buff);
listFiles(buff);
return 0;
}
void listFiles(char *path) {
char pathToUse[100];
struct dirent *dp;
char *arrayOfArraysOfChars[30][50]; // array to hold multiple single
// arrays of characters
DIR *dir = opendir(path);
printf(" %s\n", path);
return;
char *token;
const char s[2] = "-";
int counter = 0;
char pathToSave[100];
while ((dp = readdir(dir)) != NULL) {
token = strtok(dp->d_name, "");
while (token != NULL) {
if (strcmp(token, ".") != 0) {
if (strcmp(token, "..") != 0) {
strcpy(pathToSave, "");
strcpy(pathToSave, path);
strcat(pathToSave, "/");
strcat(pathToSave, token);
strcpy(arrayOfArraysOfChars[counter], pathToSave);
counter += 1;
}
}
token = strtok(NULL, s);
}
}
printf("%s\n", "sdasdasdssad");
printf("%s\n", arrayOfArraysOfChars[0]);
printf("%s\n", arrayOfArraysOfChars[1]);
printf("%s\n", arrayOfArraysOfChars[2]);
printf("%s\n", arrayOfArraysOfChars[3]);
closedir(dir);
}
arrayOfArraysOfChars is populated with the information I need. But I would like to be able to access this array from the main function. How would I do this?
I am assuming your compiler is warning you about returning local variables.
char *arrayOfArraysOfChars[30][50]
The memory used by this variable will be reused for the next stack frame when the function is finished, overwriting it and making it useless.
a) Pass it in as a parameter
b) Make it static (yuk)
c) Dynamically allocate it and return the pointer
Also, consider using a linked list of allocated strings rather than an array as I guess you don't know for sure how many files you're going to find or how long their names are.

Conflicting types when returning array of strings

I want to catch an array of filenames(strings) from getListOfFiles() and use it in my main. I have tried my every idea and there is still appearing an error:
gcc testowe.c -o test testowe.c: In function ‘main’:
testowe.c:8:15: warning: implicit declaration of function ‘getListOfFiles’ [-Wimplicit-function-declaration]
char **list = getListOfFiles(argv[1]);
testowe.c:8:15: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
testowe.c: At top level:
testowe.c:11:8: error: conflicting types for ‘getListOfFiles’
char** getListOfFiles(char *path) {
testowe.c:8:15: note: previous implicit declaration of ‘getListOfFiles’ was here
char **list = getListOfFiles(argv[1]);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
int main(int argc, char *argv[])
{
char **list = getListOfFiles(argv[1]);
}
char** getListOfFiles(char *path) {
int n=0, i=0;
DIR *d;
struct dirent *dir;
d = opendir(path);
while((dir = readdir(d)) != NULL) {
if ( !strcmp(dir->d_name, ".") || !strcmp(dir->d_name, "..") )
{
} else {
n++;
}
}
rewinddir(d);
char **filesList;
filesList = malloc((n + 1)*sizeof(char*));
while((dir = readdir(d)) != NULL) {
if ( !strcmp(dir->d_name, ".") || !strcmp(dir->d_name, "..") ){
}else {
filesList[i] = (char*) malloc (strlen(dir->d_name)+1);
strncpy (filesList[i],dir->d_name, strlen(dir->d_name) );
i++;
}
}
filesList[i] = NULL;
closedir(d);
return filesList;
}
What's the real problem cause I think all types and pointers look fine?
Read the warnings: implicit declaration of function ‘getListOfFiles’.
You are using getListOfFiles() not seen it before and so assumes that it returns an int. You can solve by either declaring the function before defining it. char** getListOfFiles(char *path) near the top of your file or for this simple case just move the whole definition before main()

Why can't I call my function(C)?

This is part of a program where I call a function that reads components from a ".dat" file and save the input to members of a Struct. When I try calling the function from my main.c it gives various errors depending on what I try. Most notably: conflicting types of 'ReadFile' and too few arguments to function 'ReadFile'. I also get a warning "passing argument from 'ReadFile' makes integer from pointer without cast" and some infos.
This is main.c
#include "MyData.h"
#include "NodalA.h"
#include "FileHandling.h"
#include <stdio.h>
#include "windows.h"
int main(){
ComponentType *CircuitData;
int numComp = 6;
int numEl = 0;
int numNodes = 0;
CircuitData = malloc((numComp)*sizeof(ComponentType));
ReadFile(CircuitData, &numEl, &numNodes);
return 0;
}
This is FileHandling.c:
#include "FileHandling.h"
#include "stdio.h"
void ReadFile(ComponentType *CircuitData, int *numEl, int *numNodes){
numEl = 0;
numNodes = 0;
int index = 0;
FILE *data;
data = fopen("mydata.dat", "r");
if (data == NULL){
printf("Error: \"mydata.dat\" could not be opened");
}
else {
while(!feof(data)){
fscanf(data, "%s, %s, %s, %f", CircuitData[index].name, CircuitData[index].node1, CircuitData[index].node2, CircuitData[index].value);
*CircuitData[index].node1 = extractInteger(CircuitData[index].node1);
*CircuitData[index].node2 = extractInteger(CircuitData[index].node2);
if(*CircuitData[index].node1 > *numNodes)
*numNodes = *CircuitData[index].node1;
if(*CircuitData[index].node2 > *numNodes)
*numNodes = *CircuitData[index].node2;
numEl++;
index++;
}
}
fclose(data);
}
And this is MyData.h
#ifndef MYDATA_H_
#define MYDATA_H_
typedef struct Comp{
char name[5]; //Name of circuit component
char node1[5], node2[5]; //2 nodes
float value[5]; //value
}ComponentType;
#endif /* MYDATA_H_ */
Any help would be appreciated. There are more code but I think this is the most important part.
The ReadFile function name used in the program is the same as a ReadFile function in "windows.h". The error "too few arguments to function 'ReadFile'" is most likely caused by the program trying to call the the function from windows with the wrong arguments. Removing "windows.h" or renaming the function ReadFile to something else solves the problem.

Errors with gcc when compiling C program

I have a custom shell program in which I have included signal.h, unistd.h, and stdio.h. I was originally working on this in RedHat Enterprise (not sure exactly what version, but not too old) and I was able to use gcc on my program and it compiled fine and ran fine. Now I moved it over to Ubuntu and gcc is giving me some errors, the first of which is conflicting types for 'getline()'. Some other errors say incompatible implicit declaration of built-in function strlen. I have overridden the functions in question, why was this working in RedHat but not in Ubuntu? Linux is not my thing so please speak plainly. Let me know if you need more error details.
/* define a global input buffer */
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#define MAXARG 512
#define MAXBUF 512
#define BUFFER_SIZE 50
#define MAX_COMMANDS 10
char buffer [BUFFER_SIZE];
static char *prompt = "MYSHELL>";
static char inpbuf[MAXBUF];
static char *arg[MAXARG+1];
static char tokbuf[2*MAXBUF];
static char *tok = tokbuf;
char history[MAX_COMMANDS][MAXBUF];
int cmd_num;
void getline(void);
void getline() {
int length;
length = read(0, inpbuf, MAXBUF);
if (length == 0) {
printf("\n");
exit(0);
}
inpbuf[length] = '\0';
}
void processline() {
char *ptr = inpbuf;
int narg;
for (narg=0;;) {
arg[narg] = tok;
for (; *ptr == ' ' || *ptr == '\t'; ptr++)
;
while(*ptr != ' ' && *ptr != '\t' && *ptr != '\n' &&
*ptr != '\0' && *ptr != ';' && *ptr != '&')
*tok++ = *ptr++;
*tok++ = '\0';
if (narg < MAXARG)
narg++;
if (*ptr == '\n')
break;
}
// clear the input buffer
for (ptr = inpbuf; *ptr != '\n'; ptr++)
*ptr = ' ';
if (narg != 0) {
arg[narg] = NULL;
}
}
void handle_SIGINT()
{
write(STDOUT_FILENO, buffer, strlen(buffer));
}
int main()
{
int pid, exitstat, ret;
struct sigaction handler;
handler.sa_handler = handle_SIGINT;
handler.sa_flags = 0;
sigemptyset(&handler.sa_mask);
sigaction(SIGINT, &handler, NULL);
strcpy(buffer, "Caught Control C\n");
while (1) {
printf("%s ", prompt);
fflush(stdout);
getline();
processline();
if ((pid = fork()) < 0){
fprintf(stderr, "myshell: error\n");
return (-1);
}
if (pid == 0) {
execvp(*arg, arg);
fprintf(stderr, "%s\n", *arg);
exit(127);
}
waitpid(pid, &exitstat, 0);
}
return 0;
}
Simplest solution would be to rename your getline() function, e.g. to my_getline()
incompatible implicit declaration of built-in function strlen
Include <string.h>
conflicting types for 'getline()
<stdio.h> already contains a declaration of getline, so make sure that nowhere in your code you have redeclared/redefined getline()[with a different prototype].
gcc -Wall typoknig.c
typoknig.c:19: error: conflicting types for ‘getline’
//usr/include/stdio.h:671: note: previous declaration of ‘getline’ was here
typoknig.c:21: error: conflicting types for ‘getline’
//usr/include/stdio.h:671: note: previous declaration of ‘getline’ was here
Two separate declarations of getline which Andy had recommended that you use my_getline() since the former is already part of stdio.h.
typoknig.c: In function ‘getline’:
typoknig.c:27: warning: implicit declaration of function ‘exit’
typoknig.c:27: warning: incompatible implicit declaration of built-in function ‘exit’
That can't be good, man exit says right at the top:
#include <stdlib.h>
void exit(int status);
perhaps you need to include stdlib.h? What does gcc assume is the signature of an undeclared function?
typoknig.c: In function ‘handle_SIGINT’:
typoknig.c:59: warning: implicit declaration of function ‘strlen’
typoknig.c:59: warning: incompatible implicit declaration of built-in function ‘strlen’
Ouch, man strlen to the rescue:
#include <string.h>
Fortunately, string.h will help out with the next one and we already nailed exit:
typoknig.c: In function ‘main’:
typoknig.c:70: warning: implicit declaration of function ‘strcpy’
typoknig.c:70: warning: incompatible implicit declaration of built-in function ‘strcpy’
typoknig.c:85: warning: incompatible implicit declaration of built-in function ‘exit’
Ain't that pre-processor nifty?
typoknig.c:87: warning: implicit declaration of function ‘waitpid’
typoknig.c:64: warning: unused variable ‘ret’
Sayeth man waitpid:
#include <sys/types.h>
#include <sys/wait.h>
Line 64 is left as an exercise for the reader.
Getline() is not part of C standard. It is a GNU extension. In c++ Getline() is standard.
So adding to your code right before your #includes
#define _GNU_SOURCE
should fix the warning. Also see "man getline" on linux.

Resources