I have to write program in c linux for operating systems class - communicator using fifo which has to work like that:
./Speak create name (to create user)
./Speak send from to (to send msg from user to user)
./Speak history name (to read all msgs sent to user
Every msg is only sent when other person can read it and after reading it msg is deleted(because its fifo based).
My question is how can i achive that, do I have to run 2 instances of program in 2 different terminals? For example in first one I write ./Speak send from to(process waits till I open other process for reading) and in second one i type ./Speak history name(to open pipe for reading and then earlier msg gets sent and readen there). Would appreciate any advice.

Okay it's working like this not sure what was happening earlier huh, well after I read 1 token how can I acces data inside it to relink my list?

void ReadList(struct client *head)
  {
      char line[126];
    FILE* fp = fopen("data.txt","r");
    if (fp == NULL)
    {
        puts("Can't open the file");
        return 1;
    }
    while( fgets(line, sizeof(line), fp) != NULL)
    {
        char* token = strtok(line, " ");
        if( strcmp(token,"Client:") == 0)
        {
            while (token != NULL)
            {
                puts(token);
                token = strtok(NULL, " ");
            }
         }
         else
         if( strcmp(token,"Item:") == 0)
         {
             while(token != NULL)
             {
                 puts(token);
                 token = strtok(NULL, " ");
             }
         }
    }
}

Not sure which is different but the thing which you posted works but while I'm doing with my fgets doesn't work kinda strange

Seems there's some problemw with fgets as when i put data into array same way as you did it works for me and aswell this:

char *result = fgets(line,sizeof(line),fp);
printf("%s \n",result);

In console display is <null>

That's how my file looks
Client: z q
Item: kupa kkk 123.000000 kk 12.000000

Client: z c
Item: kupaaaz jkk 2.000000 k 3.000000

Well I tried with this printf("CLIENT") to see if this is even getting to strcmp but it doesnt

char *token = strtok(line," ");
puts(token);

After checking what's inside of 1st token there's basicaly garbage not Client it should be like that?

Basicaly smth like this to read if client? Btw not sure why but if here I try to use puts(token) i get garbage data not Client:

void ReadList(struct client *head)
{
    char line[300];
    FILE *fp = fopen("data.txt","r");
    if(fp = NULL)
    {
        printf("File doesn't exist");
        return NULL;
    }
fgets(line,sizeof(line),fp);

char *token = strtok(line," ");
puts(token);
if( strcmp(token,"Client:") == 0)
{
    printf("CLIENT\n");
   token = strtok(line, " ");
        while (token != NULL) {
        puts(token);
        token = strtok(NULL, " ");
        }
}
else
{

}
}

Could you explain how exactly strtok works? It's first time I'm seeing it, from what it seems it takes part of readen data from fgets but you say that after strcmp I have to loop to extract other tokens. So basicly does every next use of strtok gives next input which is after " "? If so I have to "empty" it after I process 1 line?

But how to check if line which I read from txt file starts with Client? Should I use some specific function and check line with strncmp for few first letters to see if it contains either client or item?

If I add those Client:, Item: at beginning of each line , how to read such file?

So here's my problem I have inner structure inside of client. How can I know while reading from txt file that I'm reading item data or client data for my list?

struct item
{
    char item_name[30];
    char item_state[30];
    float item_price;
    char item_status[30];
    float item_price_if_not;
    struct item *next;
};
struct client
{
    char client_name[30];
    char client_last_name[30];
    struct item *item_data;
    struct client *next;
};
void savetxt(struct client *head)
{
    FILE *f;
 f = fopen("data.txt","w");
   if(f == NULL)
   {
       printf("error");
   }
    struct item *CurrentItem = head->item_data;
    while(head != NULL)
    {
        fprintf(f,"%s %s\n",head->client_name,head->client_last_name);
        while(CurrentItem != NULL)
        {

            fprintf(f,"%s %s %f %s %f ",CurrentItem->item_name,CurrentItem->item_state,CurrentItem->item_price,CurrentItem->item_status,CurrentItem->item_price_if_not);
            CurrentItem = CurrentItem->next;
        }
        head = head->next;
        if(head != NULL)
{
          CurrentItem = head->item_data;
}
        fprintf(f,"\n\n");
    }
    fclose(f);
    return NULL;
}

So basicaly all I should change is this current = prev->next and unless I want to delete all items with given name break loop?I guess that's all I needed got some time left till deadline so could aswell try to add files to my project and learn about them a bit. Could you suggest which one would be easier to use with lists? Well overall that's all probably will need some more help with files, thanks for your help.

So I wrote code to delete item it seems to be working could you check if everything is right?

void DeleteItem(struct client *head,char name[30])
        {
            struct item *current = head->item_data,*prev = NULL;
            if(head==NULL)
                printf("List empty...");
            while(current!=NULL)
            {
                if(strcmp(current->item_name,name) == 0)
                {
                    if(prev == NULL)
                    {
                        head->item_data = current->next;
                    }
                    else
                    {
                        prev->next=current->next;
                    }
                    free(current);
                }
                    prev = current;
                    current = current->next;

        }
        printf("\nElement deleted \n");
            return NULL;
        }

Okay writting code for edit was pretty simple got it done all thats left is how to delete single node from inner list. I understand that if I want to delete first element of inner list I should set it's first element to next one(is that right?) but when I want to delete something in middle of list I have to delete node and connect 2 other nodes , I seen few examples of how to delete nodes but I still dont understand how it should be done for node in middle

So to change for example name and last name of client I would have to use function find and pass node pointer to function where I changedata, malloc new data and input it here? Will it overwrite or any other action is neccessary to do so?

So basicaly to delete whole list it would be like this? Seems to be working for me not sure if I'm doing it right thought. Could you aswell explain how would I edit node?

void DeleteWholeList(struct client** head)
{
   struct client *temp;
   struct client *temporal = (*head);
   struct item* save;
   struct item* it = (*head)->item_data;
   while(temporal->next)
   {
   while(it->next)
   {
      save = it;
      it = it->next;
      free(save);
   }
   temporal->item_data = NULL;
   temp = temporal;
   temporal = temporal->next;
   free(temp);
   }
     (*head) = NULL;
 }

I'm trying to make make project for my programming class. All that's left is deleting elements and editing elements. Basicaly my question is how would I do it for my inner list? Or how would I delete single client from list? Would I first have to free the client's inner list if so how should I proceed to do so?

#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
struct date
{
    int day;
    int month;
    int year;
    struct date* next;
};
struct item
{
    char item_name[30];
   /* char item_state[30];
    double item_price;
    char item_status[30];
    double item_price_if_not;
    struct date *issue_date;*/
    struct item *next;
};
struct client
{
    char client_name[30];
    char client_last_name[30];
    struct item *item_data;
    struct client *next;
};
//ADD CLIENT//
void AddClient(struct client **head, char name[30], char last_name[30])
{
    if((*head) == NULL)
    {
        *head = malloc(sizeof(struct client));
        strcpy((*head)->client_name,name);
        strcpy((*head)->client_last_name,last_name);
        (*head)->next = NULL;
        (*head)->item_data = NULL;
    }
    else
{
    struct client *temp;
    temp = (*head);
    //             //
    while(temp->next)
    temp=temp->next;
    //              //
    (temp->next) = malloc(sizeof(struct client));
    strcpy(temp->next->client_name,name);
    strcpy(temp->next->client_last_name,last_name);
    temp->next->next = NULL;
    temp->next->item_data = NULL;
}
}
//ADD CLIENT END//
//////////////////
//FIND TO ADD//
struct client *FindToAdd(struct client *head, const char *named,const char *last_name)
{
    while(head != NULL)
    {
        if((strcmp(head->client_name,named) == 0 )&& (strcmp(head->client_last_name,last_name) == 0))
        {

            printf("Client found :%s %s\n",head->client_name,head->client_last_name);
            return head;

        }
        head = head->next;
    }
    return (NULL);
}
//FIND TO ADD END//
///////////////////
//ADD ITEM TO CLIENT//
void AddItemToClient1(struct client *head, char item_name[30]/*, char item_state[30], double price, char status[30], double price_if_not, int day, int month, int year*/)
{
    struct item* it = ...

It works thanks to code you provided, thanks.

Im writing project for my programming lessons and right now got some problems with output from function AddItemToClient, basicaly its mainly with date, in first node its correct one but after this its just random. Could someone explain what I'm doing wrong here?

#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
struct date
{
    int day;
    int month;
    int year;
    struct date* next;
};
struct item
{
    char item_name[30];
    char item_state[30];
    double item_price;
    char item_status[30];
    double item_price_if_not;
    struct date *issue_date;
    struct item *next;
};
struct client
{
    char client_name[30];
    char client_last_name[30];
    struct item *item_data;
    struct client *next;
};
//ADD CLIENT//
void *AddClient(struct client **head, char name[30], char last_name[30])
{
    if((*head) == NULL)
    {
        *head = malloc(sizeof(struct client));
        strcpy((*head)->client_name,name);
        strcpy((*head)->client_last_name,last_name);
        (*head)->next = NULL;
        (*head)->item_data = NULL;
    }
    else
{
    struct client *temp;
    temp = (*head);
    //             //
    while(temp->next)
    temp=temp->next;
    //              //
    (temp->next) = malloc(sizeof(struct client));
    strcpy(temp->next->client_name,name);
    strcpy(temp->next->client_last_name,last_name);
    temp->next->next = NULL;
    temp->next->item_data = NULL;
}
}
//ADD CLIENT END//
//////////////////
//FIND TO ADD//
struct client *FindToAdd(struct client *head, char named[30],char last_name[30])
{
    struct client *current = head;
    while(current != NULL)
    {
        if((strcmp(current->client_name,named) == 0 )&& (strcmp(current->client_last_name,last_name) == 0))
        {
            printf("Client found :%s %s\n",current->client_name,current->client_last_name);
            return current;
        }
        current = current->next;
    }
    return (NULL);
}
//FIND TO ADD END//
///////////////////
//ADD ITEM TO CLIENT//
void AddItemToClient(struct client *head, char item_name[30],char item_state[30],double price,char status[30],double price_if_not,int day,int month,int year)
{
    struct client *tempc;
    tempc = head;
    if(tempc->item_data == NULL)
    {
       tempc->item_data = malloc(sizeof(struct item));
       strcpy(tempc->item_data->item_name,item_name);
       strcpy(tempc->item_data->item_state,item_state);
       strcpy(tempc->item_data->item_status,status);
       tempc->item_data->item_price = price;
       tempc->item_data->item_price_if_not = price_if_not;
       tempc->item_data->issue_date = malloc(sizeof(struct ...

Well thanks to your help and my programming teacher figured how to do it ,thanks.

Ah sorry, this function is not neccessary. Just posted whole code on which I have been working. Only important functions are dodajprzedmiot,dodaj,find and wypisz liste. Sorry for writting it all in polish and posting here :x.

I tried even more to do it but still can't understand what's breaking while i try to add item into inner list. I'm so bad at it.. but deadline for my project is closing right now so have to do something.

    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    #include <stdio.h>

    typedef struct lista lista;
    typedef struct item item;
    struct item
    {
        char item_name[30];
        item *next;
    };
    struct lista
    {
        int liczba;
        item *data;
        char napis[10];
        lista *next;
    };
    lista* find(lista *l,char name[61])
    {
        lista *current = l;
            int i;
            for(i=1;current!=NULL;i++)
            {
                if(strcmp(current->napis,name) == 0)
                {
                    printf("[%d] %d %s\n",i ,current->liczba,current->napis);
                    return current;
                }
                current=current->next;
        }
        return (NULL);
    }
    lista *dodajprzedmiot(lista *temp, char *item_named)
    {
          if(temp->data == NULL)
        {
            temp = (lista*)malloc(sizeof(lista));
            strcpy(temp->data->item_name, item_named);
            temp->data->next = NULL;
        }
        else
        {
            lista *pom;
            pom = temp;

            while(pom->data->next) pom->data=pom->data->next;

            pom->next=(lista*)malloc(sizeof(lista));
            strcpy(pom->data->next->item_name, item_named);
            pom->data->next->next=NULL;
        }
        return (NULL);
    }
    lista* kasuj(lista *list)
    {
       lista *pom=NULL;

        while(list)
        {
            pom=list->next;
            free(list);
            list=pom;
        }
        return NULL;
    }

    void dodaj(lista **l, int n, char tab[100])
    {
        if((*l)==NULL)
        {
            *l = (lista*)malloc(sizeof(lista));
            (*l)->liczba=n;
            strcpy((*l)->napis, tab);
            (*l)->next = NULL;
        }
        else
        {
            lista *pom;
            pom=(*l);

            while(pom->next) pom=pom->next;

            pom->next=(lista*)malloc(sizeof(lista));
            pom->next->liczba=n;
            strcpy(pom->next->napis, tab);
            pom->next->next=NULL;
        }
    }

    void dodajmiejsce(lista **l, int n, char tab[100])
    {
        if((*l)==NULL)
        {
            *l = (lista*)malloc(sizeof(lista));
            (*l)->liczba=n;
            strcpy((*l)->napis, tab);
            (*l)->next =NULL;
            return;
        }

        if( n<(*l)->liczba)
        {
            lista *pom=NULL;
            lista *pom2=NULL;

            pom=(lista*)malloc(sizeof(lista));
            pom->liczba=n;
            strcpy(pom->napis, tab);
            pom2=pom;
            pom->next=(*l);
            (*l)=pom2;
            return;
        }
        else
        {
            lista *pom;
            lista *pom2;
            pom=(*l);

            while((pom->next!= NULL) && (n>pom->next->liczba)) pom=pom->next;

            pom2=pom->next;

            pom->next=(lista*)malloc(sizeof(lista));
            pom->next->liczba=n;
            strcpy(pom->next->napis, tab);
            pom->next->next=pom2;
        }
    }

    void wypiszliste(lista *lis) ...

Could you explain what exactly do you mean by coded similairy ? Uh and about a Firsitem, don't I need pointer to item struct in client, just left it named like that. While attempting to make what I wanted I tried to make it similar way to how your additem was but didnt work even a bit was smth like this:

struct item* AddItemToClient(struct client **head, char item[])
 {
    struct item *temp = malloc(sizeof(struct item));
    struct client *clienttemp= *head;
    temp->next = NULL;
    strcpy(temp->item_name,item);
    if(clienttemp->FirstItem != NULL)
    {
        clienttemp->FirstItem=temp;
    }
    else
    {
        struct item* nodeitem = FindTail(*head);
        nodeitem->next = temp;
    }
        return temp;
}

Most likely this attempt was totaly failed :p.
Um I'm using code blocks and there werent any problems during compiling, mb should I use different program?
Tried adding & but when I do it program instantly crashes after first input

Was busy lately with other subjects and now found time to get back to this not sure if you'r still watching this topic though. With help of code parts which you provided and overall looking throught internet I somehow wrote a bit of code on my own and it appears to be partialy working. It seems that it's adding items to client, but only the first one which I provide second one doesnt seem to work, and the display function aswell doesnt show second name. So if possible I would love to hear what exactly should I do to make it work propely.

`
#include<stdio.h>
#include<stdlib.h>
struct item{
char item_name[30];
struct item *next;
};
struct client{
    struct client *NextClient;
    char name[30];
    struct item *FirstItem;
};

struct client *head = NULL;
struct client *newnode = NULL;
struct client *ItemHead = NULL;
struct client* FindTailClient(struct client* head)
{
    while( head->NextClient != NULL)
    {

       head = head->NextClient;
    }
    return head;
}
struct client* AddClient(struct client** head,char name[])
{
    struct client* newnode = (struct client*)malloc(sizeof(struct client));
     if (newnode == NULL) {
    fprintf(stderr, "failed to allocate memory.\n");
    return -1;
}
       newnode->NextClient = NULL;
    strcpy(newnode->name,name);
    if(*head == NULL)
    {
        *head = newnode;
    }
      else
    {
        struct client* node = FindTailClient(*head);
        node->NextClient = newnode;
    }
    return newnode;
}
void Display(struct client *head)
{
    struct client *current = head;
    struct item *ItemCurrent;
        for(current=head;current;current=current->NextClient) {
        printf("name: %s\n", current->name);
        for(ItemCurrent=current->FirstItem;ItemCurrent;ItemCurrent=ItemCurrent->next) {
            printf("item name: %s\n",ItemCurrent->item_name);
        }
    }

    }
struct client *find(struct client *head, char name[])
{
struct client *temp = head; ...

Could you explain me why in every function you use something like: struct item* AddItem what does it change, and is there need for strcpy function in AddItem or it could be done different way as I'm not that familiar with it.
Also would like to know why in function AddItem there's struct item* head while function FindTail has struct item head .

Sorry for such questions but I'm lacking in knowledge regarding Linked lists.. and pointers trying to catch up right now while I'm free.

Back to your code, what I understood(not sure if im right..) is that the function AddItem everytime adds new node at end of the linked list kinda like that I think:

item->item->item

Based on functions which you gave with the AddItem code my guess is that I have to set head to specific client and use the AddItem function so I add 1 item to specific client and function AddItem works like it always adds another item at end of list so the links are like i written 1 post ago. Though still not sure how exactly I could link both client with list of items :/

Um, well it doesn't explain much to me seems like normal linked list for me. From what I understand mine should look like:

 client->client
      |       |
    item     item
      |       |
    item     item

So I think it should be list of items under each client node I have idea how it should be I think at least but i have no idea how it should look in code :/. Thank you for your time.. :x

So I think that those structures should look like this but how would I allocate memory when creating list here?

 struct client{
    char name[30];
    char last_name[30];
    struct item *d;
    struct client *next;
    }
    struct item{
    char item_name[30];
    struct item *next;
    }

The structures which I used were just to present my problem so those doesnt really matter all I want is example of how it can be done in c and possibly answer to further questions if I dont understand something thanks.

I have following problem:
I have 2 structures: Clients and items
for example structure clients would have name and list of items from another structure asigned to this specific name I have to do this with singly linked lists. I simply have no idea how to do this would be great if somebody could explain to me how to do this and give example of how this should look aswell.