Array has incomplete element type - c

I try to give my Void function a struct but when I do this I get a errors.
first:error: subscript of pointer to incomplete type 'struct Lager'.
and a warning:warning: incompatible pointer types passing 'Lager (*)[200]' to parameter of type 'struct Lager *' [-Wincompatible-pointer-types].
and
warning: declaration of 'struct Lager' will not be visible outside of this function [-Wvisibility].
I already asked my fellow students but no-one of them could help me.
void case1(struct Lager *wh, int l){
int end;
int v;
char ques;
do {
printf("\nEnter the product name: ");
scanf("%s", *(wh[l]).artikel);
printf("\nAmount of products: ");
scanf("%i", &*(wh[l]).anzahl);
printf("\n\nAdd another product ? (Y/N)");
// add a space before % to skip leading whitespace
scanf(" %c", &ques);
switch (ques) {
case 'Y':
v++;
l++;
break;
case 'N':
end = 1;
v = 0;
l++;
break;
default:
printf("Wrong entry\n");
end = 1;
break;
}
} while (end != 1);
if (v >= 2) {
printf("Product added successfully\n\n");
}else {
printf("Products have been successfully added\n\n");
}
}
int main() {
typedef int item;
typedef char max;
typedef int GanzvieleBuchstaben;
//unien wär die bessere variante (eigentlich). weil platzsparender
typedef struct managementtool
{
max artikel[200];
item anzahl;
}Lager;
Lager lager[200];
printf("Welcome to Warehouse Management 97\n\n\nWhat do you want to do ?\n");
GanzvieleBuchstaben a,l,f,i,v,x,p,c,я,и,ii;
int exit, end, all;
int b = 201;
char ques, nu1;
char find [100];
do {
printf("\n(1)Add article\n(2)Edit article.\n(3)Search entry.\n(4)Show stock.\n(5)Exit\n");
scanf("%i",&x);
switch (x) {
case 1://add
case1(&lager, l);
*Irrelevant stuff down there*

Related

getting bubble sort to work with structure

im not sure how to bubble sort using structures, id like the function sortMovies to be able to sort the movies alphebeticaly by title but i am getting these errors listed below.
#include <stdio.h>
#include <conio.h>
#define CONST 100
void sortMovies(struct movies main[CONST]);
void changeMovie(struct movies main);
int findMovie(struct movies main, int nOfMovies, struct movies tempMovie);
struct movies newMovie();
typedef struct movies{
char title[30];
char UPC[12];
int qnty;
double price;
}movies;
int main()
{
int nOfMovies = 0, findR, stop = 0, nOfMoviesArr[CONST];
char decider;
while (stop != 1)
{
movies main[CONST];
movies tempMovie;
printf("(A)dd a new movie\n(C)hange a Movie's Information \n(D)elete a Movie \n(L)ist All Movies\n(Q)uit");
scanf(" %c", &decider);
switch (decider)
{
case 'a':
case 'A':
tempMovie = newMovie();
nOfMovies = findMovie(main[CONST], nOfMovies, tempMovie);
nOfMovies++;
break;
case 'c':
case 'C':
printf("enter movie upc:");
scanf("%s", main);
break;
case 'l':
case 'L':
sortMovies(main[CONST]);
break;
case 'q':
case 'Q':
return 0;
break;
default:
printf("An invalid option was selected!");
}
}
}
struct movies newMovie() {
movies new;
printf("enter movie upc:");
scanf("%s", new.UPC);
printf("enter movie title:");
scanf("%s", new.title);
printf("enter movie qauntity:");
scanf("%d", new.qnty);
if (new.qnty <= 0)
{
printf("quanitity must be greater than 0");
printf("enter movie qauntity:");
scanf("%d", new.qnty);
}
printf("enter movie price:");
scanf("%lf", new.price);
if (new.price <= 0)
{
printf("price must be greater than 0");
printf("enter movie price:");
scanf("%lf", new.price);
}
return new;
}
int findMovie(struct movies main, int nOfMovies, struct movies tempMovie)
{
int count;
for (count = 0; count < nOfMovies; count++)
{
if (tempMovie.UPC == main.UPC)
{
return count;
}
else
{
printf("error");
return -1;
}
}
}
void changeMovie(struct movies main)
{
char decider;
printf("would you like to change the value? y or no input");
switch (decider)
{
case 'y':
case 'Y':
printf("enter movie title:");
scanf("%c", main.title);
printf("enter movie qauntity:");
scanf("%d", main.qnty);
if (main.qnty <= 0)
{
printf("quanitity must be greater than 0");
printf("enter movie qauntity:");
scanf("%d", main.qnty);
}
printf("enter movie price:");
scanf("%lf", main.price);
if (main.price <= 0)
{
printf("price must be greater than 0");
printf("enter movie price:");
scanf("%lf", main.price);
}
break;
return 0;
}
}
void sortMovies(struct movies main[CONST])
{
int i, sflag, count = 0;
char temp;
do
{
sflag = 0;
for (i = 1; i < CONST; i++)
{
if (main[i - 1].title > main[i].title)
{
temp = main[i - 1].title;
main[i - 1].title = main[i].title;
main[i].title = temp;
sflag = 1;
}
}
count++;
} while (sflag);
for (i = 0; i < CONST; i++)
{
printf("%c\t%c\t%d\t%lf", main[i].title, main[i].UPC, main[i].qnty, main[i].price);
}
} ```
Severity Code Description Project File Line Suppression State Suppression State
Error C2440 'function': cannot convert from 'movies' to 'movies *' 40
Error (active) E0167 argument of type "movies" is incompatible with parameter of type "struct movies *" 40
Error (active) E0137 expression must be a modifiable lvalue 148
Error C2106 '=': left operand must be l-value 148
Error (active) E0137 expression must be a modifiable lvalue 149
Error C2106 '=': left operand must be l-value 149
Error (active) E0167 argument of type "movies" is incompatible with parameter of type "struct movies *" 40
This is happening because with main[CONST] you are trying to pass a single element of of the main array (the element at index CONST), rather than the whole array when the sortMovies method expects an array. To pass the whole array into the function, use sortMovies(main);.
Error (active) E0137 expression must be a modifiable lvalue 148
Error C2106 '=': left operand must be l-value 148
Error (active) E0137 expression must be a modifiable lvalue 149
Error C2106 '=': left operand must be l-value 149
This is happening because you are trying to copy the contents of one char array to another with the = operator, which is not valid. Instead, use strcpy(main[i - 1].title, main[i].title) and strcpy(main[i].title, temp).
Also, in your sortMovies function you declare temp as a char which you try to use to swap the title strings. What you want here is instead char* temp. If you are not familiar with this syntax, I would recommend reading up on pointers in C. They are a very important construct in the language, and a better understanding of pointers will likely also help you clear up a lot of the issues you are having with this program.

*Beginner *C confusing me with Warnings

so I declared a float named price and when I try to compile it I get a waring that it would be a double, can someone tell me why C think that this is a double ?
B3N2.c:37: warning: format specifies type 'float *' but the argument has type 'double' [-Wformat]
scanf("%f", la[i].preis);
int main(int argc, char *argv[]) {
struct Lager {
char artikel[200];
int anzahl;
float preis;
} la[200];
printf("Wilkommen bei Lagerverwaltung 97\n\n\nWas möchten sie tun ?\n");
int exit = 0;
int x,v;
int f = 1;
int i = 0;
char ques;
int end;
do {
printf("\n(1)Artikel hinzufügen\n(2)Artikel entnehmen.\n(3)Eintrag suchen.\n(4)Lager ausgeben.\n(5)Exit\n");
scanf("%x",&x);
switch (x) {
case 1://add
do {
printf("\nGebe den namen des Produkts an: ");
scanf("%s", la[i].artikel);
printf("\nAnzahl der verfügbaren Produkte: ");
scanf("%i", &la[i].anzahl);
printf("\ngib den preis des artikels an: ");
scanf("%f", la[i].preis);
printf("\n\nWeiteres Produkt hinzufügen ? (J/N)");
scanf("%s", &ques);
switch (ques) {
case 'J':
v++;
f++;
break;
case 'N':
end = 1;
v = 0;
break;
default:
printf("Falsche Eingabe\n");
break;
}
} while (end != 1);
if (v >= 2) {
printf("Produkt wurde Erfolgreich hinzugefügt\n\n");
}else {
printf("Produkte wurden Erfolgreich hinzugefügt\n\n");
}
break;
sorry for the dumb question but I tryed to fix it and now i'm totally Overwhelmed
scanf() needs a pointer to the space (that is, the variable) where the scanned value will be stored. But your call hands over the value of la[i].preis which is a float that is cast automatically into a double.
Change your code to give the address of la[i].preis to scanf() by using the & operator like this:
scanf("%f", &la[i].preis);

I cant seem to understand how to restrict my scanf to only numbers of float

#include <stdio.h>
#include <string.h>
#define mL 5
#define NL 20
#define UL 6
struct LIST
{
char n[NL];
float am;
char u[UL];
};
struct array
{
struct LIST array;
};
void addCityInformation(struct array *add, int *items);
void printCities(struct array *all, int items);
int main(void)
{
struct array shopping[mL];
int choice, nrOfItemsAdded = 0;
do
{
printf("\nWhat du you want to do?");
printf("\n1 - add grocery");
printf("\n2 - print shopping list");
printf("\n3 - exit");
printf("\nYour choice: ");
scanf("%d", &choice);
while(getchar() != '\n');
switch (choice)
{
case 1:
addCityInformation(&shopping[nrOfItemsAdded], &nrOfItemsAdded);
break;
case 2:
printCities(shopping, nrOfItemsAdded);
break;
case 3:
printf("Exiting program\n\n");
break;
default:
printf("Invalid input\n\n");
break;
}
}
while(choice != 3);
return 0;
}
int clean_stdin()
{
while (getchar()!='\n');
}
void addCityInformation(struct array *add, int *items)
{
if(*items == mL)
printf("No more space in the list\n");
else
{
printf("Enter name: ");
fgets(add->array.n, NL, stdin);
add->array.n[strlen(add->array.n)-1] = '\0';
do {
printf("Enter amount: ");
}while (scanf("%f", &add->array.am )); //loop untill other than float
getchar();
printf("Enter unit: ");
fgets((add->array.u), UL, stdin);
add->array.u[strlen(add->array.u)-1] = '\0';
(*items)++;
}
}
void printCities(struct array *all, int items)
{
printf("\n\n%-20s %-15s %-9s | %-6s\n", "Name", "amount", "unit");
printf("--------------------------------------------------------\n");
for(int i = 0; i < items; i++)
printf("%-20s %-15.1f %-9.4s \n", all[i].array.n, all[i].array.am, all[i].array.u);
}
This is my loop beside that i am only showing a part of the code. It now just continues to give enter amount and letting me register it in the struct. I want to restrict the user to only entering positive numbers and no character at all. And if he types a character it should rerun the loop even if it is 123Av123 it should run the loop and only register the correct number
Edit: now showing the whole code//loop untill other than float is what i want help with
int check=scanf("%f", &add->array.am )
if(check!=1||add->array.am<0){
printf("Incorrect input");
return 1;
}
I think that will do it.
Edit: you wanted it to rerun after so use continue; instead of return;

Having trouble with C pointers

First of all, im a begginer C programmer, studying in a university. I need to do a program that is kinda like a data base. Thus far i have made the function to input new data, it works, but compiler shows a few warning and notes, i tried a lot of things, but nothing helped. Here is the code:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
struct subjects{
char *subjName[100];
char *lectName[100];
char *lectSurname[100];
double credits;
double studentnum;
}subj;
char subjectname[][100];
char lecturername[][100];
char lecturersurname[][100];
int credits[100];
int students[100];
int newentry=0;
void listInput();
void listEdit();
void listDelete();
void listPrint();
int userChoice();
int main() {
int select;
int r=1;
while(r!=0){
select=userChoice();
switch(select){
case 1:
listPrint();
break;
case 2:
listInput();
break;
case 3:
listDelete();
break;
case 4:
listEdit();
break;
case 0:
r=0;
break;
}
}
return 0;
}
int userChoice(){
int choice,input=0,check;
printf("(1). View all the data\n");
printf("(2). Enter new data\n");
printf("(3). Delete data\n");
printf("(4). Edit data\n");
printf("(0). Exit\n");
printf("-----------------------------\n");
while(input!=1){
printf("Enter your choice\n");
scanf("%d", &choice);
if(choice>4 || choice<0){
printf("Invalid input \n");
}
else
input = 1;
}
return choice;
}
void listPrint(){
for(int i=0; i<newentry; i++){
printf("%d, %s, %s, %s, %d, %d\n",i+1, subjectname[i], lecturername[i], lecturersurname[i], credits[i], students[i]);
}
}
void listInput(){
int i;
char firstLetter,term;
printf("Enter the name of the subject \n");
while(scanf("%s", &subj.subjName)!=1)
printf("Error, subject name must be a text ");
printf("Enter the name of the lecturer \n");
int valid=0;
while(valid!=1){
while(scanf("%s", &subj.lectName)!=1)
printf("Error, lecturer's' name must be a text ");
firstLetter=*subj.lectName;
if(firstLetter>65 && firstLetter<90 && isalpha(firstLetter)){
valid=1;
}
else
printf("Error, lecturer's name must start with a capital letter, try again \nEnter the name of the lecturer \n");
}
valid=0;
printf("Enter the surname of the lecturer\n");
while(valid!=1){
while(scanf("%s", &subj.lectSurname)!=1)
printf("Error, lecturer's surname must be a text ");
firstLetter=*subj.lectSurname;
if(firstLetter>65 && firstLetter<90 && isalpha(firstLetter)){
valid=1;
}
else
printf("Lecturer's surname must start with a capital letter, try again \nEnter the surname of the lecturer \n");
}
printf("Enter the amount of credits in course \n");
while(1){
scanf("%lf", &subj.credits);
if(subj.credits<0 || subj.credits != (int)subj.credits)
printf("Error, amount of credits must be a positive integer, try again \n");
if(subj.credits>0 && subj.credits == (int)subj.credits)
break;
}
printf("Enter the number of students \n");
while(1){
scanf("%lf", &subj.studentnum);
if(subj.studentnum<0 || subj.studentnum != (int)subj.studentnum)
printf("Error, number of students must be a positive integer,try again \n");
if(subj.studentnum>0 && subj.studentnum == (int)subj.studentnum)
break;
}
printf("Added a new entry.\n\n");
strncpy(subjectname[newentry], subj.subjName, 99);
strncpy(lecturername[newentry], subj.lectName, 99);
strncpy(lecturersurname[newentry], subj.lectSurname, 99);
credits[newentry]=subj.credits;
students[newentry]=subj.studentnum;
newentry++;
}
void listDelete(){
printf("33333333333");
}
void listEdit(){
printf("4444444");
}
And the warnings:
In function 'listInput':
96 14 [Warning] assignment makes integer from pointer without a cast
108 14 [Warning] assignment makes integer from pointer without a cast
132 33 [Warning] passing argument 2 of 'strncpy' from incompatible pointer type
79 9 [Note] expected 'const char * restrict' but argument is of type 'char **'
133 34 [Warning] passing argument 2 of 'strncpy' from incompatible pointer type
79 9 [Note] expected 'const char * restrict' but argument is of type 'char **'
134 37 [Warning] passing argument 2 of 'strncpy' from incompatible pointer type
79 9 [Note] expected 'const char * restrict' but argument is of type 'char **
At top level:
14 6 [Warning] array 'subjectname' assumed to have one element
15 6 [Warning] array 'lecturername' assumed to have one element
16 6 [Warning] array 'lecturersurname' assumed to have one element
What can i do to fix those warnings? The program works just fine, but i cant pass if i dont fix the warnings.
Here is a better way to do things
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char *subjName;
char *lectName;
char *lectSurname;
double credits;
double num_students;
}Subject;
typedef struct{
Subject **subjs;
int num_subjs;
}Subjects;
void listInput();
void listEdit();
void listDelete();
void listPrint();
int userChoice();
int main() {
Subjects *subjects = malloc(sizeof(Subjects));
subjects->num_subjs = 0;
subjects->subjs = NULL;
int r=1;
while(r!=0){
int select=userChoice();
switch(select){
case 1:
listPrint(subjects);
break;
case 2:
listInput(&subjects);
break;
case 3:
listDelete();
break;
case 4:
listEdit();
break;
case 0:
r=0;
break;
}
}
return 0;
}
int userChoice(){
int choice,input=0,check;
printf("(1). View all the data\n");
printf("(2). Enter new data\n");
printf("(3). Delete data\n");
printf("(4). Edit data\n");
printf("(0). Exit\n");
printf("-----------------------------\n");
while(input!=1){
printf("Enter your choice\n");
scanf("%d", &choice);
if(choice>4 || choice<0){
printf("Invalid input \n");
}
else
input = 1;
}
return choice;
}
void listPrint(Subjects *subjects){
for(int i=0; i< subjects->num_subjs; i++){
printf("%d, %s, %s, %s, %d, %d\n",i+1, subjects->subjs[i]->subjName, subjects->subjs[i]->lectName, subjects->subjs[i]->lectSurname, subjects->subjs[i]->credits, subjects->subjs[i]->num_students);
}
}
char *getln()
{
char *line = NULL, *tmp = NULL;
size_t size = 0, index = 0;
int ch = 1;
while (ch) {
ch = getc(stdin);
if (ch == '\n')
ch = 0;
if (size <= index) {
size += 1;
tmp = realloc(line, size);
if (!tmp) {
free(line);
line = NULL;
break;
}
line = tmp;
}
line[index++] = ch;
}
return line;
}
int isText(char *str,char *name){
for(int i = 0; i < strlen(str);i++){
if((str[i]<'A' || str[i]>'z') && str[i]!=' '){
printf("Error, %s must be a text \n",name);
return 0;
}
}
return 1;
}
int isNegative(int n){
if(n < 0){
printf("Error, number of students must be a positive integer,try again \n");
return 1;
}
return 0;
}
void listInput(Subjects **p_subjects){
while ( getchar() != '\n' );
Subject *new_subj = malloc(sizeof(Subject));
new_subj->subjName = NULL;
new_subj->lectName = NULL;
new_subj->lectSurname = NULL;
new_subj->credits = 0;
new_subj->num_students = 0;
do{
printf("Enter the name of the subject \n");
new_subj->subjName = getln();
}while(!isText(new_subj->subjName,"Subject name"));
do{
printf("Enter the name of the lecturer \n");
new_subj->lectName = getln();
}while(!isText(new_subj->lectName,"Lecturer's name"));
do{
printf("Enter the surname of the lecturer\n");
new_subj->lectSurname = getln();
//Convert to uppercase
new_subj->lectSurname[0] &= '_';
}while(!isText(new_subj->lectSurname,"Lecturer's surname"));
do{
printf("Enter the number of credits \n");
scanf("%d", &new_subj->credits);
}while(isNegative(new_subj->num_students));
do{
printf("Enter the number of students \n");
scanf("%d", &new_subj->num_students);
}while(isNegative(new_subj->num_students));
(*p_subjects)->subjs = realloc((*p_subjects)->subjs,sizeof(Subject*)*(++(*p_subjects)->num_subjs));
(*p_subjects)->subjs[(*p_subjects)->num_subjs-1] = new_subj;
printf("Added a new entry.\n\n");
}
void listDelete(){
printf("33333333333");
}
void listEdit(){
printf("4444444");
}

C dynamic struct error

#include <stdio.h>
#include <stdlib.h>
int main()
{
int size,choice;
printf("student size:\n");
scanf("%d", &size);
typedef struct
{
int age;
double gpa;
char name[];
}STUDENT;
STUDENT *array = (STUDENT *) malloc(sizeof(STUDENT) * size);
printf("\n(1) Add a student\n(2) Delete a student\n(3) Save all students\n(4)Quit\n");
scanf("%d",&choice);
while (choice != 4){
switch (choice) {
STUDENT temp;
STUDENT *tempptr = &temp;
int cellNum;
case 1:
printf("Enter age gpa and name:\n");
scanf("%d %f %s",&tempptr->age,&tempptr->gpa,&tempptr->name);
printf("Enter cell number:\n");
scanf("%d", &cellNum);
if (cellNum > (size-1)){
printf("Invalid cell number\n");
break;
}else{
*(array + cellNum) = temp;
}
case 3:
printf("stupid c syntax rules");
FILE *p = fopen("students.txt","w");
int i = 0;
for (i=0; i<size; i++){
fprintf(p, "%d, %f, %s\n",*(array+i).age,*(array+i).gpa,*(array+i).name);
}
}
printf("\n(1) Add a student\n(2) Delete a student\n(3) Save all students\n(4)Quit\n");
scanf("%d",&choice);
}
return 0;
}
getting errors:
main.c:40:56: error: request for member 'age' in something not a structure or union
fprintf(p, "%d, %f, %s\n",*(array+i).age,*(array+i).gpa,*(array+i).name);
^
main.c:40:71: error: request for member 'gpa' in something not a structure or union
fprintf(p, "%d, %f, %s\n",*(array+i).age,*(array+i).gpa,*(array+i).name);
^
main.c:40:86: error: request for member 'name' in something not a structure or union
fprintf(p, "%d, %f, %s\n",*(array+i).age,*(array+i).gpa,*(array+i).name);
why is this happening?
Thanks
The . operator is a higher precedence than unary * (refer here). So first (before dereferencing) the compiler is trying to find an age field in (array+i), which is not a structure, but a pointer.
You want to replace the *(array+i).age by either (array+i)->age or (*(array+i)).age.

Resources