struct reviewStruct {
char reviewer[MAX_STR];
int feedback[NUMBER_MOVIES];
};
int readMovies(FILE *file, char movieNames[NUMBER_MOVIES][MAX_STR])
int readReviews(FILE *file, struct reviewStruct reviews[NUMBER_REVIEWERS])
int main() {
FILE *file;
char movieNames[NUMBER_MOVIES][MAX_STR];
char reviews [NUMBER_REVIEWERS];
myFile("cisfile.txt");
readMovies(file, movieNames);
readReviews(file, reviews);
}
This is my main function along with the function definitions, when I compile the program I get the following errors:
"warning: passing argument 2 of ‘readReviews’ from incompatible pointer type" for the line: "readReviews(file, reviews);"
"warning: ‘file’ is used uninitialized in this function" for the line: "readMovies(file, movieNames);"
How do I fix these two errors?
I took your code and tried to make it run.
#include <stdio.h>
#include <stdlib.h>
#define MAX_STR 10
#define NUMBER_MOVIES 3
#define NUMBER_REVIEWERS 2
struct reviewStruct {
char reviewer[MAX_STR];
int feedback[NUMBER_MOVIES];
};
int readMovies(FILE *file, char movieNames[NUMBER_MOVIES][MAX_STR])
{
printf("hi\n");
}
int readReviews(FILE *file, void *reviews)
{
printf("bye\n");
}
int main(void)
{
FILE *myFile;
char movieNames[NUMBER_MOVIES][MAX_STR];
char reviews [NUMBER_REVIEWERS];
myFile = fopen("cisfile.txt","r");
readMovies(myFile, movieNames);
readReviews(myFile, reviews);
fclose(myFile);
return 0;
}
With these assumptions runs without any warnings.
I am using gcc 8.3.0 without any options.
1. First warning:
As per what #kaylum said. You are declaring char reviews[MUMBER_REVIEWERS], but when you defined the parameters for your function: int readReviews(FILE *file, struct reviewStruct reviews[NUMBER_REVIEWERS], it is clear that the parameter concerned by the array should be of type struct reviewStruct.
So in the line where you got the warning change: char reviews [NUMBER_REVIEWERS]; to struct reviewStruct reviews[NUMBER_REVIEWERS];. That should be a pointer to a structure type, not a pointer to a character type. Or if you want to go more in detail: It is a pointer to an array of structures, the type of the array is determined by the type of elements it holds.
2. Second warning:
Now let's take a look at the second warning: warning: ‘file’ is used uninitialized in this function" for the line: "readMovies(file, movieNames)
As the warning says. Your pointer file was not initialized. Take it as a rule, that you cannot use a pointer without initializing it to something to point to. I believe that you are trying to read from a stream. So just in case you need it, you perhaps may be willing to use the function fopen(), which returns a pointer to a stream.
Related
I'm working with C, and not allowed to use C++. Currently, I'm trying to implement some level of OOP in C. I'm currently working on trying to implement polymorphism and inheritance.
I've spent the majority of the day reading up on how my goals are possible through the use of function pointers. I am attempting to print the members variables of both structs as seen here:
RecordObject.h
typedef struct SuperRecordObject
{
char *Id;
char *date;
char *cases;
char *deaths;
void (*ptrPrintRecord)(char *id, char *date, char *cases, char *deaths, char *names_fr, char *names_en);
} SuperRecord;
typedef struct ChildRecordObject
{
SuperRecord super;
char *names_fr;
char *names_en;
} ChildRecord;
I have defined the function ptrPrintRecord in this file:
RecordObject.c
#include <stdio.h>
#include "RecordObject.h"
void ptrPrintRecord(char *id, char *date, char *cases, char *deaths, char *names_fr, char *names_en)
{
//char *record;
printf(" %s | %s | %s | %s | %s | %s\n", id, date, cases, deaths, names_fr, names_en);
//return record;
}
And I try to use the function in this file, as such:
DataLayer.c
#include <stdio.h>
#include <string.h>
#include "RecordObject.h"
/* more code here */
void(*fun_ptr)(char*,char*,char*,char*,char*,char*) = &record.super.ptrPrintRecord; //
(*fun_ptr)(record.super.Id, record.super.date, record.super.cases, record.super.deaths, record.names_fr, record.names_en);
/* more code here */
However, when I compile (using GCC), I get this warning which causes a crash.
warning: initialization of 'void (*)(char *, char *, char *, char *, char *, char *)' from incompatible pointer type 'void (**)(char *, char *, char *, char *, char *, char *)' [-Wincompatible-pointer-types]
62 | void(*fun_ptr)(char*,char*,char*,char*,char*,char*) = &record.super.ptrPrintRecord;
I've ran some other pointer functions in other files to mess around and test it, and the only thing I can think of as to what's going on here is it's maybe got something to do with how strings work in C?
You have an extraneous & in your attempted function pointer assignment. The ptrPrintRecord member of your structure is already a function pointer of the correct type, so you don't need the & - which would give the address of that pointer.
Just use:
void(*fun_ptr)(char*, char*, char*, char*, char*, char*) = record.super.ptrPrintRecord; // No &
As a side note, your use of ptrPrintRecord as that member (function pointer) and also as the name of an actual function (with the same 'signature') is likely to cause some issues, further down the road.
Furthermore, you need to actually initialize that member (pointer) to a valid function address before copying it to something you then call (as also with the other members of the structure). Here's a small main (using your other code) that works:
int main()
{
ChildRecord record;
record.super.ptrPrintRecord = ptrPrintRecord; // See my note about the name clash!
record.super.Id = "ID";
record.super.date = "today";
record.super.cases = "cases";
record.super.deaths = "deaths";
void(*fun_ptr)(char*, char*, char*, char*, char*, char*) = record.super.ptrPrintRecord; //
// To call the pointed-to function, we can just use the pointer name:
fun_ptr(record.super.Id, record.super.date, record.super.cases, record.super.deaths, record.names_fr, record.names_en);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
char *preorden="GEAIBMCLDFKJH";//line 5
error in the above line
char *inorden="IABEGLDCFMKHJ";//line 6
error in this line
char *postorden;
error in this line
void post(char *pre, char *in, char *pos,int n)
{
int longIzqda;
if(n!=0){
pos[n-1]=pre[0];
longIzqda=strchr(in,pre[0])-in;
post (pre+1,in,pos,longIzqda);
post (pre+1+longIzqda,in+1+longIzqda,pos+longIzqda,n-1-longIzqda);
}
}
int main(int argc,char *argv[])
{
int aux;
aux=strlen(preorden);//convert to string
postorden=(char *)malloc(aux*sizeof(char));//use of malloc function
if (postorden){
printf("The preorden is: %s\n",preorden);
printf("The inorden is: %s\n",inorden);
post(preorden,inorden,postorden,aux);
postorden[aux]='\0';
printf("The postorden calculated is: %s\n",postorden);
free(postorden);
}
else{
fprintf(stderr,"Whithout memory\n");
return 1; // return 1
}
return 0;
}
the error is in the line 5 and 6
the compiler says:
deprecated conversion from string constant to 'char*' [-Wwrite-strings]
There are few issues with your code, firstly this
char *preorden="GEAIBMCLDFKJH";//line 5
forces compiler to warn you like below if compiled with -Wwrite-strings flags in C
deprecated conversion from string constant to 'char*'
[-Wwrite-strings]
because the string literal GEAIBMCLDFKJH stored in read only section of primary memory i.e pointer where it points, that contents is read only, hence instead of char* use const char*. for e.g
char *preorden = "GEAIBMCLDFKJH";/* preorden is normal pointer but "GEAIBMCLDFKJH" is read only, hence error */
And
const char *preorden = "GEAIBMCLDFKJH"; /* const char *ptr means ptr contents is read only */
Secondly, here
postorden=(char *)malloc(aux*sizeof(char));//use of malloc function
casting of malloc result is not required as malloc() return type is void* which is automatically and safely promoted to any other pointer type, Read Do I cast the result of malloc?. for e.g
postorden = malloc(aux * sizeof(*postorden));//use of malloc function
Also here(this point is about wrong comment on below line, please don't mind)
aux=strlen(preorden);//convert to string
strlen(preorden) returns the length of string pointed by preorden and gets assigned to aux not as written in comments(convert to string).
And change the post() definition to
void post(const char *pre, const char *in, char *pos,int n) {
/* some code*/
}
The message “deprecated conversion from string constant to 'char*' [-Wwrite-strings]” arises because the code was compiled as C++ code, which has different rules about string literals and pointer conversions from C.
This can be fixed by compiling the code as C code or worked around by inserting an explicit cast to char *.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_BUFFER_SIZE 100
typedef struct config_struct config_t ;
struct config_struct{
char name[20];
char ip[20];
int port;
char log[100];
};
int main(int argc, char *argv[]) {
config_t config;
read_config_file(argv[1], &config);
return 0;
}
int read_int_from_config_line(char* config_line) {
int val = atoi(config_line);
return val;
}
void read_str_from_config_line(char* config_line, char* val) {
strncpy(val,config_line, MAX_BUFFER_SIZE);
}
void read_config_file(char* config_filename, config_t *config) {
FILE *fp;
char *value, buffer[MAX_BUFFER_SIZE];
fp = fopen("./settings.conf", "r");
while (fgets(buffer, MAX_BUFFER_SIZE, fp) != NULL) {
if(!strcmp(buffer,"NAME")) {
read_str_from_config_line(value, &(config->name));
}
if(!strcmp(buffer,"PORT")) {
&(config->port) = read_int_from_config_line(value);
}
}
}
I try to compile this code and it gives me a incompatible pointer type at read_str_from_config_line(value , &(config->name)); and lvalue required as left operand of assignment &(config->port) = read_int_from_config_line(value);
I am trying to return the stuct back to the main program but I'm having problem with the struct pointers.
Any solution for it to be solve?
PS: The code is a mess as I trying to shorten it. Any help will be good as I am still a beginner to C programming.
Thanks
The & operator means "take the address of the object to the right".
This:
&(config->port)
means "take the address of the port member of the structure pointed to by config.
You don't want to take the address, you just want to assign to the member. That's just:
config->port = ...
This is the same as (*config).port, but nobody writes it like that since the arrow operator is so convenient.
read_str_from_config_line(value, &(config->name));
confg->name is declared as a char array, which naturally decays to a pointer to the first element (of type "pointer-to-char") if you omit the &:
read_str_from_config_line(value, config->name);
Taking its address explicitly instead results in a pointer of type pointer-to-array-of-20-chars, which is not the same type as pointer-to-char - which is why you are getting an error. This is a common source of confusion in C; in general, you should not take the address of an array (although it does have legitimate use cases).
In this line:
&(config->port) = read_int_from_config_line(value);
You are taking the address of the port member of the structure pointed at by config, which is a non-lvalue pointer. It looks like you are actually trying to assign to the member, so the line should read:
config->port = read_int_from_config_line(value);
#include <stdio.h>
#include <string.h>
struct students{
char name[50];
int age;
int height;
};
int main(int argc, char **argv)
{
struct students manoj;
strcpy(manoj.name, "manojkumar");
manoj.age = 15;
displaymanoj(&manoj); //print testing \n , name , age
return 0;
}
void displaymanoj(struct students *ptr) {
printf("Testing...............DEBUG\n");
printf("%s\t%d\n", ptr->name,ptr->age);
printf("END OF TEST: SUCESS -manoj-");
}
I am learning C and it's working where is use pointer to point to structure variable. I am getting the correct output when I run the program. Just that my Geany IDE giving out some message which I would like to know why.
My Compiler Message as below :
You must declare the functions before calling them.
So your program should look something like
// Includes
// Structure
// Function prototype declaration
// This was what you were missing before
void displaymanoj(struct students *ptr);
int main(int argc, char **argv)
{
...
}
void displaymanoj(struct students *ptr) {
...
}
Since you have the definition of displaymanoj() isn't seen when you call it from main(), compiler implicitly declares one with return type int
which conflicts with the actual one. Note that the implicit declaration has been removed since the C99 standard and is no longer valid.
To fix it:
1) Either move the function displaymanoj() above main()'s definition or
2) Do a forward declaration of displaymanoj().
I always thought that when you want to return an array from a function, the only way to do that was using pointers like so:
char * func();
But yesterday, while I was going through K & R, I noticed wrongly assumed that char x()[] is also a valid construct. So I went ahead to test this out and wrote up the following code:
#include <stdio.h>
#include <stdlib.h>
char string1[10] = "123456789";
char x(void)[10];
int main(void) {
printf("string returned by x() is %s",x());
return EXIT_SUCCESS;
}
char x(void)[10] {
return x;
}
Compiling using GCC on Windows, this threw the following errors:
..\src\07arrreturn.c:7:6: error: 'x' declared as function returning an array
..\src\07arrreturn.c: In function 'main':
..\src\07arrreturn.c:10:2: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'int' [-Wformat]
..\src\07arrreturn.c: At top level:
..\src\07arrreturn.c:14:6: error: 'x' declared as function returning an array
..\src\07arrreturn.c: In function 'x':
..\src\07arrreturn.c:15:2: warning: return makes integer from pointer without a cast [enabled by default]
What is happening? am I mis-understanding what the book says? How can you return more than one value (or address) from a function? Isn't that restricted by the fact that you only have a single limited size CPU register that can hold the return value? If you have to return a big chunk of data, you can do so only by returning the address to it right?
Whats the deal with char x()[]? Is such a thing even used?
EDIT: I DID in fact misread the stuff from K&R. See comment below.
char x()[] is also a valid construct
Not as-is, and not quite in this context.
You can use similar syntax to:
declare a pointer to array: char (*arrPtr)[20];
declare an array of function pointers: void (*foo[20])(void);
dereference the return value (pointer) of a function call: char *foo(); char c = foo()[0];
declare a function that returns a pointer to array: char (*foo())[20]
or the same thing with a function pointer: char (*(*foo)())[20]
Which one of these are you looking for?
The C standard (ISO/IEC 9899:2011) says unequivocally:
6.7.6.3 Function declarators (including prototypes)
Constraints
1 A function declarator shall not specify a return type that is a function type or an array
type.
Thus your code is invalid.
K&R C is quite old. In ANSI C (C89), functions returning arrays aren't allowed and what you see is the result of this. First, you get errors for the declaration of x() as a function returning an array and due to this error, x() is never correctly declared and thereby treated like a function returning an int (because this used to be the default return type). This returned int is then supposed to be interpreted as char * generating the final warning.
If you need to return an array, you can wrap it in a struct. Otherwise return a pointer (make sure that the memory it points to is valid after returning).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char string1[10] = "123456789";
struct ret_s {
char string1[10];
};
struct ret_s x(void);
int main(void) {
struct ret_s r = x();
printf("string returned by x() is %s\n", r.string1);
return EXIT_SUCCESS;
}
struct ret_s x(void) {
struct ret_s r;
strcpy(r.string1, string1);
return r;
}