C - Strings are giving me errors - c

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

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;
}

Problem in my program code of c please help me in resolving the problem

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');

Read string C - Linux

I'm trying to read a string and print it in Linux using:
cc child.c -o child
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
char st[100];
scanf("%s", &st);
printf("%s", st);
return 0;
}
However I encounter this warning that will not allow me to compile.
child.c: In function ‘main’:
child.c:8:2: warning: format ‘%s’ expects argument of type ‘char ’, but argument 2 has type ‘char ()[100]’ [-Wformat=]
scanf("%s", &st);
How can I solve it? Thanks!
In C, when passed to a function, array names converted to pointer to the first element of array. No need to place & before st. Change
scanf("%s", &st);
to
scanf("%s", st);
In C array types degenerate to pointers. So when you take the address of an array, you actually get a pointer to a pointer. Just pass the array itself to scanf.

Structs and char strings [duplicate]

This question already has answers here:
Why does reading into a string buffer with scanf work both with and without the ampersand (&)?
(2 answers)
Closed 8 years ago.
#include <stdio.h>
#define MAX 3 // students in class
#define LEN 20 // max lengths stydent's name
typedef struct {
char name[LEN];
int am;
float tv;
}student;
void read (student board[]) { //this function should fill the board of structs
int i;
for (i=0; i<MAX; i++) {
printf("\n give student's name");
scanf ("%s",&board[i].name);
}
}
void read (student board[]);
int main (void) {
student class[MAX];
read (class);
return 0;
}
when i try to compile it i get this error
let2.c:15:3: warning: format ‘%s’ expects argument of type ‘char ’, but argument 2 has type ‘char ()[20]’ [-Wformat=]
let2.c:15:3: warning: format ‘%s’ expects argument of type ‘char ’, but argument 2 has type ‘char ()[20]’ [-Wformat=]
Lose the & in your scanf call. You want a pointer to the first character of the string, not a pointer to the array itself:
scanf("%s", board[i].name);
Or, equivalently:
scanf("%s", &board[i].name[0]);

listing conditionally an array of strings

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.

Resources