listing conditionally an array of strings - c

I'm trying to list all files and folders in a given directory in C, the following code errors out and i cant figure out whats wrong
#include <sys/types.h>
#include <dirent.h>
#include <regex.h>
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
enum {
WALK_OK = 0,
WALK_BADPATTERN,
WALK_BADOPEN,
};
int walk_directories(const char *dir, const char *pattern, char* strings[])
{
struct dirent *entry;
regex_t reg;
DIR *d;
int i = 0;
//char array[256][256];
if (regcomp(&reg, pattern, REG_EXTENDED | REG_NOSUB))
return WALK_BADPATTERN;
if (!(d = opendir(dir)))
return WALK_BADOPEN;
while (entry = readdir(d))
if (!regexec(&reg, entry->d_name, 0, NULL, 0) )
//puts(entry->d_name);
strings[i] = (entry->d_name);
i++;
closedir(d);
regfree(&reg);
return WALK_OK;
}
void main()
{
struct passwd *pw = getpwuid(getuid());
char *homedir = pw->pw_dir;
strcat(homedir, "/.themes");
int n = 0;
char *array[256][100];
char *array2[256][100];
walk_directories(homedir, "", array);
for (n = 0; n < 256; n++)
{
//do stuff here later, but just print it for now
printf ("%s\n", array[n]);
}
walk_directories("/usr/share/themes", "", array2);
for (n = 0; n < 256; n++)
{
//do stuff here later, but just print it for now
printf ("%s\n", array2[n]);
}
}
The error at compile time is
test2.c: In function ‘main’:
test2.c:42:2: warning: incompatible implicit declaration of built-in function ‘strcat’ [enabled by default]
test2.c:48:2: warning: passing argument 3 of ‘walk_directories’ from incompatible pointer type [enabled by default]
test2.c:15:5: note: expected ‘char **’ but argument is of type ‘char * (*)[100]’
test2.c:52:6: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat]
test2.c:55:2: warning: passing argument 3 of ‘walk_directories’ from incompatible pointer type [enabled by default]
test2.c:15:5: note: expected ‘char **’ but argument is of type ‘char * (*)[100]’
test2.c:59:6: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat]
If it helps, I've implemented what I want already in python, this is the desired result for C
import os
DATA_DIR = "/usr/share"
def walk_directories(dirs, filter_func):
valid = []
try:
for thdir in dirs:
if os.path.isdir(thdir):
for t in os.listdir(thdir):
if filter_func(os.path.join(thdir, t)):
valid.append(t)
except:
logging.critical("Error parsing directories", exc_info=True)
return valid
def _get_valid_themes():
""" Only shows themes that have variations for gtk+-3 and gtk+-2 """
dirs = ( os.path.join(DATA_DIR, "themes"),
os.path.join(os.path.expanduser("~"), ".themes"))
valid = walk_directories(dirs, lambda d:
os.path.exists(os.path.join(d, "gtk-2.0")) and \
os.path.exists(os.path.join(d, "gtk-3.0")))
return valid
print(_get_valid_themes())
thank you
[EDIT]
thanks for the help, only problem im having now is the printf's all spit out rubbish instead of what i expected, ive tried a few things and the while loop looks like this now
while (entry = readdir(d))
if (!regexec(&reg, entry->d_name, 0, NULL, 0) )
//printf("%s\n",entry->d_name);
strcpy(strings[i], (entry->d_name));
//strings[i] = (entry->d_name);
printf("%i\n",i);
i++;
closedir(d);
the i doesnt get printed properly either, this is all i get from the 3 printf statements
0
Adwaita2
\#
0
Radiance
��
\#
�K��
� `���
����
�
��
�
.N=
�O��
�
�
should mention that if i enable
printf("%s\n",entry->d_name);
then it prints the expected output though

You should include string.h to get the declaration of strcat(3).
In your declaration:
int walk_directories(const char *dir, const char *pattern, char* strings[])
The char *strings[] is just syntactic sugar meaning char **strings. Since you're passing a 2D array, that won't work. It looks to me like you're intending to make two arrays of strings, but that's not what these declarations do:
char *array[256][100];
char *array2[256][100];
You probably don't want the *s there. If you take them off, you can change the signature of walk_directories to this:
int walk_directories(const char *dir, const char *pattern, char strings[][100])
And it should work, with the necessary changes inside your function to match. As a bonus, this change will make your printf calls start working, too.
It looks like you're missing some braces around your while loop body.

The first warning indicates that the compiler cannot figure out what arguments the strcat() function is supposed to take. Since this is a standard C function, this warning means that you are missing a #include directive. Specifically, you need to #include <string.h>. When you fix this, you may find that you get different errors and warnings, so work from there.

Related

Why is print portion of this program that takes info of 11 cars and prints the model name of red cars not working?

here is the code
#include <stdio.h>
#include <string.h>
int main()
{
int val;
struct info{
char model[50];
int price;
char color[30];
}car[11];
int i;
for(i=0;i<11;i++)
{
printf("Enter model name:\n");
scanf("%s",&car[i].model);
printf("Enter price:\n");
scanf("%d",&car[i].price);
printf("Enter color:\n");
scanf("%s",&car[i].color);
}
printf("\nThe red cars are:\n");
for(i=0;i<11;i++)
{
val=strcmp("red",tolower(car[i].color));
if(0==val)
{
printf("%d. %s\n",i+1,car[i].model);
}
}
return 0;
}
also I tried using gets for string input but it doesn't seem to work.
Here are the warnings:
*main.c:17:17: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[50]’ [-Wformat=]
scanf("%s",&car[i].model);
main.c:21:17: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[30]’ [-Wformat=]
scanf("%s",&car[i].color);
main.c:26:34: warning: passing argument 1 of ‘tolower’ makes integer from pointer without a cast [-Wint-conversion]
val=strcmp("red",tolower(car[i].color));
In file included from main.c:4:0:
/usr/include/ctype.h:124:12: note: expected ‘int’ but argument is of type ‘char *’
extern int tolower (int __c) __THROW;
main.c:26:26: warning: passing argument 2 of ‘strcmp’ makes pointer from integer without a cast [-Wint-conversion]
val=strcmp("red",tolower(car[i].color));
In file included from main.c:2:0:
/usr/include/string.h:144:12: note: expected ‘const char *’ but argument is of type ‘int’
extern int strcmp (const char *__s1, const char *__s2)
You posted your compiler output. Good. Let's look at all those errors:
main.c:17:17: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[50]’
Most of the time, when you call scanf, you need & on the variable being stored, but %s is an exception. (Explanation elsewhere.) Get rid of the &: scanf("%s",car[i].model);
main.c:26:34: warning: passing argument 1 of ‘tolower’ makes integer from pointer without a cast
This is your main problem. Your program as written will never work. tolower expects a single character to convert, but you're passing it a pointer instead. (You're passing it a pointer to the entire string you want to convert.)
/usr/include/ctype.h:124:12: note: expected ‘int’ but argument is of type ‘char *’
This is another message explaining the tolower problem.
main.c:26:26: warning: passing argument 2 of ‘strcmp’ makes pointer from integer without a cast
tolower returns the single character it has converted. But strcmp expects an entire string.
/usr/include/string.h:144:12: note: expected ‘const char *’ but argument is of type ‘int’
This is another message explaining the tolower/strcmp problem.
How to fix this? There is not a standard function (that I can remember) that converts an entire string to lowercase. You'd have to write that yourself. Another option is to use a version of strcmp that compares the strings without regard to case. Two such functions (neither of which is quite standard, however) are strcasecmp and stricmp.
tolower only works with char not string, so use the function on every char of the string.
#include <string.h>
#include <stdio.h>
#include <ctype.h>
int strcicmp(char const *a, char const *b)
{
if (!a && !b)
return 0
else if (!a || !b)
return -1
for (;; a++, b++) {
int d = tolower((unsigned char)*a) - tolower((unsigned char)*b);
if (d != 0 || !*a)
return d;
}
}
int main()
{
int val;
struct info{
char model[50];
int price;
char color[30];
}car[11];
int i;
for(i=0;i<11;i++)
{
printf("Enter model name:\n");
scanf("%s",&car[i].model);
printf("Enter price:\n");
scanf("%d",&car[i].price);
printf("Enter color:\n");
scanf("%s",&car[i].color);
}
printf("\nThe red cars are:\n");
for(i=0;i<11;i++)
{
val=strcicmp(car[i].color, "red");
if(0==val)
{
printf("%d. %s\n",i+1,car[i].model);
}
}
return 0;
}

strtok return int type in c

When I run this code it gave a segmentation fault.
main ()
{
char *line ="2,3,22";
int size=3,i,j;
double value;
char *val;
for (i = 0; i<size ; i++) {
if (line == NULL) break;
printf("%s\n",strtok (line ,","));
}
}
and gave a
"warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
printf("%s\n",strtok (line ,","));"
So when I assign strtok value to char* it gave an error. why strtok return an int value? What is the solution?
It's using an implicit prototype for strtok. You need to #include <string.h> (You might also need to include stddef.h for NULL and should also include stdio.h for printf).

char comparison wrong output and no comparison in C

C is not comparing characters. I have tried many times and always with problems here.
My code is
#include <stdio.h>
#include <string.h>
int main(){
int palavra[16];
int frase[201];
gets(palavra);
gets(frase);
printf("%s\n",palavra);
printf("%s\n",frase);
int i;
int palavrasNaFrase=0;
int tamanhoPalavra=strlen(palavra);
int tamanhoFrase=strlen(frase);
printf("tamanho frase %d\n",tamanhoFrase);
for(i=0; i<tamanhoFrase; i++){
printf("i = %d\n",i);
printf("caracter: %c\n",palavra[0]);
printf("caracter: %c\n",frase[i]);
if(frase[i] == palavra[0]){
printf("C is not comparing characters\n");/*
int j=i+1,k=1;
int letrasIguais=1;
int cont=1;
while(cont<tamanhoPalavra){
if(frase[j]==palavra[k]){
letrasIguais++;
}
j++;
k++;
cont++;
}
if(letrasIguais==tamanhoPalavra){
palavrasNaFrase++;
}*/
}
}
//printf("%d\n",palavrasNaFrase);
return(0);
}
the input
ANA
ANAGOSTADEUMABANANA
the out
ANA
ANAGOSTADEUMABANANA
tamanho frase 19
i = 0
caracter: A
caracter: A
i = 1
caracter: A
caracter: O
i = 2
caracter: A
caracter: D
i = 3
caracter: A
caracter: A
i = 4
caracter: A
caracter: A
C is not comparing characters
i = 5
caracter: A
caracter: ©
i = 6
...
caracter: ­
0
Process returned 0 (0x0) execution time : 4.696 s
Press any key to continue.
Is so bugged, that i dont know what to do.
Please someone help me, if someone can find what is the problem, why is so bugged. There is soooo many bugs and things happening that should not be happening. I have tried and search so many times and always i have found the way to compare strings char by char using string[position]==string2[position] was right but in this program is not working and i have no idea why so many bugs! Please someone help me and give me a light! What am i doing wrong? Thanks
you're defining the arrays like this:
int palavra[16];
int frase[201];
while it reserves enough space, there's a problem when you're comparing char to char: you compare int to int (multi-char to multi-char) probably what you want here (and you probably had warnings about pointer types that you ignored):
if(frase[i] == palavra[0]){
You have to change your declarations to use char instead
char palavra[16];
char frase[201];
Compiling with warnings on you get this as expected. Fixing the warning would fix your code as well (extract of the warnings, redundant ones edited out):
$ gcc -Wall toto.c
toto.c: In function 'main':
toto.c:8:10: warning: passing argument 1 of 'gets' from incompatible pointer type
gets(palavra);
^
In file included from toto.c:1:0:
c:\gnatpro\7.4.2\x86_64-pc-mingw32\include\stdio.h:491:17: note: expected 'char *' but argument is of type 'int *'
^
In file included from toto.c:1:0:
c:\gnatpro\7.4.2\x86_64-pc-mingw32\include\stdio.h:491:17: note: expected 'char *' but argument is of type 'int *'
char *__cdecl gets(char *_Buffer) __MINGW_ATTRIB_DEPRECATED_SEC_WARN;
^
^
toto.c:11:5: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'int *'
[-Wformat=]
printf("%s\n",frase);
^
toto.c:14:31: warning: passing argument 1 of 'strlen' from incompatible pointer type
int tamanhoPalavra=strlen(palavra);
^

Cannot Use Printf!?! (while performing hashing algorithm using mhash)

I am using Mhash and I would like to print the length of my blocksize for debugging purposes, but I keep getting an error every time I try to compile
Any suggestions on how I can fix this error?
Here is my code:
#include <mhash.h>
#include <stdio.h>
#include <string.h>
// 0x12e6bc6e68c3b9506e6668db6b7224f894fab073728fc179 (TIGER192) (48)
int main()
{
char password[] = "Jefe";
int keylen = 4;
char data[] = "what do ya want for nothing?";
int datalen = 28;
MHASH td, td2;
unsigned char *mac, *mac2;
int i, j;
td = mhash_hmac_init(MHASH_TIGER192, password, keylen, mhash_get_hash_pblock(MHASH_TIGER192));
mhash(td, data, datalen);
mac = mhash_hmac_end(td);
printf("0x");
for (i = 0; i < mhash_get_block_size(MHASH_TIGER192); i++)
{
printf("%.2x", mac[i]);
}
printf("\n");
// int length = strlen(mac);
// printf(length);
// int length = 5;
// printf(length);
exit(0);
}
I run the program with the following commands:
hb2#hb1:~/Desktop$ gcc -o hashexample hashexample.c -lmhash
hb2#hb1:~/Desktop$ ./hashexample
0x12e6bc6e68c3b9506e6668db6b7224f894fab073728fc179
And it runs successfully, but when I try to print the length of the hashed result, I get the following error!!? Any ideas on why?
// int length = strlen(mac);
// printf(length);
hb2#hb1:~/Desktop$ gcc -o hashexample hashexample.c -lmhash
hashexample.c: In function ‘main’:
hashexample.c:33:2: warning: passing argument 1 of ‘printf’ makes pointer from integer without a cast [enabled by default]
/usr/include/stdio.h:363:12: note: expected ‘const char * __restrict__’ but argument is of type ‘int’
hashexample.c:33:2: warning: format not a string literal and no format arguments [-Wformat-security]
At first, I thought it was because I thought I was using strlen incorrectly?! But even when I try to do a simple printf of an integer, I still get an error:
// int length = 5;
// printf(length);
hb2#hb1:~/Desktop$ gcc -o hashexample hashexample.c -lmhash
hashexample.c: In function ‘main’:
hashexample.c:35:2: warning: passing argument 1 of ‘printf’ makes pointer from integer without a cast [enabled by default]
/usr/include/stdio.h:363:12: note: expected ‘const char * __restrict__’ but argument is of type ‘int’
hashexample.c:35:2: warning: format not a string literal and no format arguments [-Wformat-security]
Thanks for your help in advance!
Check the man page for printf(). The first argument is a const char *. You're passing an int.
That's what the warning says too:
warning: passing argument 1 of ‘printf’ makes pointer from integer without a cast [enabled by default]
You wanted:
printf("%d", length);
You need the format string to specify that an int is going to be printed.

warning to pass argument 1 of ‘fopen’ from incompatible pointer type

My program takes two files with words sorted as parameter and performs the mixture into 1 single file called final_sorted.txt.the program runs successfully and creates the mixed file, even ignoring repeated words, but the compiler tells me some warnings that are not as removed.
equipo01#equipo01-desktop:~/Escritorio/mezclar (2)$ gcc meclapro.c -o mixmeclapro.c: In function ‘mix_files’:
meclapro.c:10: warning: passing argument 1 of ‘fopen’ from incompatible pointer type
/usr/include/stdio.h:249: note: expected ‘const char * __restrict__’ but argument is of type ‘char **’
meclapro.c:11: warning: passing argument 1 of ‘fopen’ from incompatible pointer type
/usr/include/stdio.h:249: note: expected ‘const char * __restrict__’ but argument is of type ‘char **’
meclapro.c: In function ‘main’:
meclapro.c:69: warning: passing argument 1 of ‘mix_files’ from incompatible pointer type
meclapro.c:6: note: expected ‘char **’ but argument is of type ‘char *’
meclapro.c:69: warning: passing argument 2 of ‘mix_files’ from incompatible pointer type
meclapro.c:6: note: expected ‘char **’ but argument is of type ‘char *’
this is my code, which takes which takes the command line parameter
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void mix_files(char **file1, char **file2){
FILE *a1, *a2, *output;
char aux1 [10000],aux2 [10000];
a1 = fopen(file1, "r");
a2 = fopen(file2, "r");
ouput = fopen ("final.txt", "w+");
// read the first line of each file:
fscanf(a1,"%s",aux1);
fscanf(a2,"%s",aux2);
// loop, while !feof for both file
while(!feof(a1) && !feof(a2)) {
// Select the line to add
if(strcasecmp(aux1,aux2) < 0){
// add the line
fprintf(output,"%s\n",aux2);
//read the next line from aux2
fscanf(a2,"%s",aux2);
}
else if(strcasecmp(aux1,aux2)>0){
fprintf(salida,"%s\n",aux1);
fscanf(a1,"%s",aux1);
}
if (strcasecmp(aux1,aux2)==0){
//printf("repetidas\n");
fprintf(salida,"%s\n",aux1);
fscanf(a1,"%s",aux1);
fscanf(a2,"%s",aux2);
}
}
if(!feof(a1)){
while(!feof(a1)) {
fscanf(a1,"%s",aux1);
fprintf(salida,"%s\n",aux1);
}
}
if(!feof(a2)){
while(!feof(a2)) {
fscanf(a2,"%s",aux2);
fprintf(salida,"%s\n",aux2);
}
}
}
int main(int argc, char *argv[]){
mix_files(argv[2], argv[1]);
return(0);
}
I would like someone to help me discover the reason for the warning and how could I fix, thanks in advance for your answers, sorry for my English
Change:
void mix_files(char **file1, char **file2){
to:
void mix_files(char *file1, char *file2){
or better still:
void mix_files(const char *file1, const char *file2){
You will then be passing the correct type (char *) from main to mix_files, and this in turn will also fix the problem when you call fopen.

Resources