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

There are many ways to accomplish it. You could add a small item at the beginning of each line that identifies it as either client or item.

 fprintf(f,"Client: %s %s\n",head->client_name,head->client_last_name);

 fprintf(f,"Item:  %s %s %f %s %f ",CurrentItem->item_name,CurrentItem->item_state,CurrentItem->item_price,CurrentItem->item_status,CurrentItem->item_price_if_not);

Edited 2 Years Ago by Ancient Dragon

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

Read a line. If it starts with Client then you know you have to allocate a new client node. If it starts with Item then add a new Item node to the most recent Client node.

Edited 2 Years Ago by Ancient Dragon

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?

This is one way to do it.

fgets(line,sizeof(line),fp);
// get first token on the line
char* token = strtok(line," ");
if( strcmp(token,"Client:") == 0)
{
   // process line as client
   // call strtok() in a loop to extract the other tokens

}
else
{
    // process line as item
   // call strtok() in a loop to extract the other tokens
}

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?

Yes, it works something like that. Example:

char line[] = "one two three 123 456";

char* ptr = strtok(line," ")
while( ptr != NULL)
{
   puts(ptr);
   ptr = strtok(NULL," ");
}

The first time strtok is called with a charater array. After that, the first parameter to strtok() is NULL. It will return NULL then the last token has been read, normally meaning end-of-data.

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
{

}
}

line 17 the first parameter to strtok() should be NULL, because it's alredy been called with line as the first parameter on line 12.

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

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?

post the line that was read from the file. If the program doesn't print "CLIENT" like you had on line 16 then my guess is the line in the file doesn't contain the word "Client" at the beginning -- remember capitalization is important, so Client and client and client: are not the same.

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

You must be doing something else wrong. This works ok for me

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable: 4996)

int main()
{
    char line [] = "Client: z q";
    char* token = strtok(line, " ");
    if( strcmp(token,"Client:") == 0)
    {
        puts("CLIENT");
        while (token != NULL)
        {
            puts(token);
            token = strtok(NULL, " ");
        }
    }

}

And the console display is this:

CLIENT
Client:
z
q
Press any key to continue . . .

Edited 2 Years Ago by Ancient Dragon

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>

Edited 2 Years Ago by zaxo311

Nothing wrong with fgets()

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable: 4996)

int main()
{
    char line[126];
    FILE* fp = fopen("TextFile.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)
        {
            puts("CLIENT");
            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

I did this and it still works ok

    char* result;
    while( (result = fgets(line, sizeof(line), fp)) != NULL)
    {
        puts(result);
        char* token = strtok(line, " ");

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, " ");
             }
         }
    }
}
This question has already been answered. Start a new discussion instead.