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);
^
Related
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;
}
WHY I AM getting ERROR during COMPILATION with GCC even i have putted the ch variable as char type?
my program:
#include <stdio.h>
void circular(int*,int*,int*);
int main(){
int n1,n2,n3,flag=1;
char fb='y';
do{
printf("enter the value of x,y,z resp.: ");
scanf("%d%d%d",&n1,&n2,&n3);
circular(&n1,&n2,&n3);
printf("after %d circular shift values are: \nx= %d\ny= %d\nz= %d\nwant to do circular shift again(y/n): ",flag,n1,n2,n3);
scanf("%s",fb);
flag+=1;
}while(fb=='y' || fb=='Y');
return 0;
}
void circular(int *n1,int *n2,int *n3){
int temp;
temp=*n1;
*n1=*n2;
*n2=*n3;
*n3=temp;
}
error after compiling with gcc:
c4q13.c: In function ‘main’:
c4q13.c:22:11: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
22 | scanf("%s",fb);
| ~^ ~~
| | |
| | int
| char *
As the message says, the variable fb has type char and it is promoted to int in variable-number arguments. You have to pass char* for %s in scanf().
Also %s reads strings (sequence of characters terminated by a null-character), so passing a pointer to an one-character buffer for %s is bad, causing dangerous out-of-range access.
You should allocate an array for string and pass a pointer to its element. Also you should set the maximum number of characters to read to avoid buffer overrun. Considering the terminating null-character, the limit should be (at most) the number of elements in the buffer minus one.
Things to change:
char fb='y';
scanf("%s",fb);
}while(fb=='y' || fb=='Y');
They should be:
char fb[4]="y";
scanf("%3s",fb);
}while(fb[0]=='y' || fb[0]=='Y');
I am learning functions in C and having following problem with so many warnings :-(
code is as follows
#include <stdio.h>
void main(){
int a,c;
char *b; // declaring a pointer
char string[100]="something";
b = string; // assigning a pointer.. doing
printf("\n %s \n\n %s",string,*b); // doing this as a verification of the pointer, which is good - no seg faults
printf("Enter a and c:-");
scanf("%d %d",&a,&c);
find(a,c,*b);
printf("%s",*b);//segmentation fault core dumped:-'(
}
void find(int x, int y,char *b){
if(x>y)
*b = "a is greater than b";
else if(x=y)
*b = "both the values are equal";
else
*b = "b is greater than a";
}
warnings while compiling:--
function.c: In function ‘main’:
function.c:7:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
printf("\n %s \n\n %s",string,*b); /*doing this jus to check is pointer working but no it is *not.segmentation error here "core dumped":-'(
^
function.c:12:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
printf("%s",*b);//segmentation fault core dumped:-'(
^
function.c: At top level:
function.c:14:6: warning: conflicting types for ‘find’ [enabled by default]
void find(int x, int y,char *b){
^
function.c:11:2: note: previous implicit declaration of ‘find’ was here
find(a,c,*b);
^
function.c: In function ‘find’:
function.c:16:6: warning: assignment makes integer from pointer without a cast [enabled by default]
*b = "a is greater than b";
^
function.c:18:6: warning: assignment makes integer from pointer without a cast [enabled by default]
*b = "both the values are equal";
^
function.c:20:6: warning: assignment makes integer from pointer without a cast [enabled by default]
*b = "b is greater than a";
while running
segmentation error (core dumped)
Working cod:=---- with the help of community
#include <stdio.h>
#include <malloc.h>
void main(){
int a,c;
char *b =(char *)malloc(100);
char string[100]="something";
b = &string;
printf("\n %s \n\n %s",string,b);
printf("Enter a and c:-");
scanf("%d %d",&a,&c);
find(a,c,*b);
printf("\n%s",b);
}
void find(int x, int y,char *b){
if(x>y)
b = "a is greater than b";
else if(x=y)
b = "both the values are equal";
else
b = "b is greater than a";
}
output:-
something
something
enter a and c:-
10
20
something
**
means still it is not updating the value in the function...
**
I fix your code in less than a minute.No warnings and probably works (I don't speaking for logical problems).This means that your warnings were common mistake that even an experienced engineer might do.However a smart engineer will use warnings to fix these warnings.
#include <stdio.h>
#include <malloc.h>
void find(int, int,char*);
int main(){
int a,c;
char *b = NULL;
char string[100]="something";
b = &string[0];
printf("\n %s \n\n %s",string,b);
printf("Enter a and c:-");
scanf("%d %d",&a,&c);
find(a,c,b);
printf("\n%s",b);
return 0;
}
void find(int x, int y,char *b){
if(x>y)
b = "a is greater than b";
else if(x == y)
b = "both the values are equal";
else
b = "b is greater than a";
}
If you check this , you will see that there is no warning now.
Regarding on your effort to learn , I would try to explain warnings and try to estimate and give you a big picture of what those warnings would result.
warning: return type of ‘main’ is not ‘int’
-Here you take the answers in why we prefer to return int in main.
int main vs void main
warning: suggest parentheses around assignment used as truth value
-This is the worst error you have. = is for asign , == is for comparison
Difference between = and ==
The other too errors ,
conflicting type
and
implicit declaration
means that preprocessor of your compiler reached function invocation ( find(a,c,*b); ) before the declaration of the function.So one compiler might fix that and auto resolve this while another compiler might have an error.That's why preprocessor check firstly the header file , but since you don't have a header file (that's bad) , you should have a declaration of the function before you invoke this.
Whilst you fix that you would receive a warning ,
warning: passing argument 3 of ‘find’ makes pointer from integer
without a cast
This means that you are trying to pass the pointer of the pointer. b was a pointer at the first place , which hold the address of the first element of your char array.So y should have pass this without *.
THIS is a very good example on the question Why we don't ignore error
.Because an error about implicit declaration of a function , led as to discover another error , more significant than the first , that was hiding under the first warning.
Another note is that you don't need to malloc there.You malloc when you want to allocate an amount of memory on the heap and keep it alive before you free it.
PS:I hope I help and I hope you also take some benefit out of these.If you have any question , do not hesitate to comment(better in chat , to avoid spam in the community)
Thank you.
So I am writing a simple code to print out each symbol in my string. When compiling it, it gives me an error tough that I do not understand:
The code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void) {
char my_string[50];
int i, n;
printf("Type in a string please : ");
scanf("%s", &my_string);
n = strlen(my_string);
for (i = 0;i < n; i++) {
printf("%c",my_string[i]);
}
}
The error it gives:
gcc yl2.c -o Yl2
yl2.c: In function ‘main’:
yl2.c:9:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[50]’ [-Wformat=]
scanf("%s", &my_string);
^
What is the problem here?
scanf("%s", &my_string); there should not be a &.
Since you have declared char my_string[50]; my_string as character array which is of type char * which is expecting in scanf() as the warning states.
Just use, scanf("%s", my_string);. Base address of the array as argument is sufficient.
scanf("%s", &my_string); should be scanf("%s", my_string);
my_string is an array, which decays to a pointer when you type it out without [ ].
If you type &my_string, you get an array pointer, which is strictly speaking not the same thing. That's why the compiler complains.
&my_string is a pointer to my_string i.e. a ‘char (*)[50]’
You can either use
scanf("%s", &my_string[0]);
or more conventionally
scanf("%s", my_string);
remove & sign in scan, it will work
Also no need to use string.h here
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(®, pattern, REG_EXTENDED | REG_NOSUB))
return WALK_BADPATTERN;
if (!(d = opendir(dir)))
return WALK_BADOPEN;
while (entry = readdir(d))
if (!regexec(®, entry->d_name, 0, NULL, 0) )
//puts(entry->d_name);
strings[i] = (entry->d_name);
i++;
closedir(d);
regfree(®);
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(®, 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.