问题
I'm working on an exercise in c the last few days and I'm having this warning (as the title suggests). I've tried a bunch of stuff but I don't really know how to exactly fix this. I'm not good at programming so there are mistakes. Below are the structs I'm using (which cannot be changed because that's how they are given):
typedef struct bookR* book;
struct bookR{
char author[MAXSTRING];
enum genres{fiction,scientific,politics};
int id;
char review[MAXLINES][MAXSTRING];
};
typedef struct nodeR* node;
struct nodeR{
book b;
node next;
};
typedef struct listR* list;
struct listR{
node head, tail;
int size;
};
And here is part of the code where the problem occurs:
void addBook(book b, list bList){
char author [MAXSTRING];
int id;
char review [MAXSTRING][MAXLINES];
printf ("Give the author,`enter code here` id and review of the new book respectively");
scanf("%s",author);
scanf("%d",&id);
scanf("%s",review);
node k=(node)malloc(sizeof(struct nodeR));
assert(k);
k->next=NULL;
strcpy(k->b->author,author);
k->b->id=id;
strcpy(k->b->review,review[MAXSTRING]);}
And this is the warning I'm getting:
warning: format '%s' expects argument of type 'char *' but argument 2 has type 'char (*)[100]' [-Wformat=]
scanf("%s",review);
warining:passing argument 1 of 'strcpy' from incompatible pointer tupe [-Wincompatible-pointer-types]
strcpy(k->b->review,review[MAXSTRING]);
Any help is much appreciated. Thanks for your time and sorry for the long post.
回答1:
Warning No1
In order to use
scanf
, you need to pass a pointer to it. You have declared :char review [MAXSTRING][MAXLINES];
but you read :
scanf("%s",review);
You need to change this to :
scanf("%s", review[i]);
where
i
is an index from0
toMAXSTRING-1
.Warning No2
Moreover, the statement :
strcpy(k->b->review,review[MAXSTRING]);
gets out of bounds, as you the positions of your array reach
review[MAXSTRING-1]
. Apart from that, you are assigning a line to a whole array. So you should change it to :strcpy(k->b->review[index], review[MAXSTRING-1]);
Two more notes :
- See this link on why not to cast the result of malloc.
Keep in mind that in a declaration such as :
array[x][y];
x
indicates the lines andy
indicates the columns. You have them in the opposite way, so make sure that you do not get confused and that you really access rows when you want rows and columns when you want columns.
回答2:
1st warning
char review [MAXSTRING][MAXLINES];
it is a matrix, that can be seen as an array of C-strings in your case.
Each C-String is review[index]
where index goes from 0
to MAXSTRING-1
So
scanf("%s",review)
is wrong because of you must pass a single C-String to function, then you must write:
scanf("%s",review[index]);
I'd suggest you to limit the input string to the maximum allowed chars for each string MAXLINES-1
using, instead of scanf
:
fgets(review[index], MAXLINES, stdin);
2nd warning
Same thing for review
member of struct bookR
.
So
strcpy(k->b->review,review[MAXSTRING]);
must be
strcpy(k->b->review[index],review[MAXSTRING-1]);
As you can see there is a second problem into your strcpy call: the second parameter address your array of strings out of bound, that invoke Undefined Behavior.
Other warnings
There is an warning more into your code:
test.c:666:45: warning: declaration does not declare anything
enum genres{fiction,scientific,politics};
^
Final Considerations
I guess you want to switch defines into your matrix definitions, as you done into struct bookR
, like:
char review [MAXLINES][MAXSTRING];
I Think could be a best choice to ask for each single data with a specific prinf
ans its scanf
/fgets
.
printf ("Give the author: ");
fgets(author, MAXSTRING, stdin);
printf ("Enter id: ");
scanf("%d",&id);
printf ("Enter review of the new book respectively: ");
fgets(review[index], MAXSTRING, stdin);
来源:https://stackoverflow.com/questions/37291409/c-errorformat-s-expects-argument-of-type-char-but-argument-2-has-type-ch