Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using fgets() to read multiple lines. How to go to the Next line?

Tags:

c

So I am opening a file that contains cards data for a card game I am designing for my assignment, basically each line contains 104 characters and each line is equal to a deck of card.

I'm using a char **** because of

  1. number of decks
  2. num of players (4)
  3. num of cards (13)
  4. card is represented like 9H, 3D means nine of hearts and three of diamonds, so it uses 2 characters.

I want to use fgets() to read multiple lines but I'm not sure if this works...

for loop is just the way how the deckfile is set, I just want to know if the fgets will go to the next line when it hits \n...

    di->cards = (char ****)malloc(sizeof(char***) * di->numDecks);
    for (i = 0; i < di->numDecks; i++) {
        di->cards[i] = (char ***)malloc(sizeof(char**) * 4);
        for (j = 0; j < 4, j++) {
            di->cards[i][j] = (char **)malloc(sizeof(char*) * 13);
            for (k = 0, k < 13, k++) {
                di->cards[i][j][k] = (char *)malloc(sizeof(char) * 3);
            }
        }
    }

    for (i = 0; i < di->numDecks, i++) {
        for (j = 0; j < 13, j++) {
            for (k = 0; k < 4; k++) {
                while ((fgets(cards[i][k][j], 3, di->deckFile)) != NULL);
            }
        }
    }
like image 591
Kevin Ko Avatar asked Dec 26 '22 19:12

Kevin Ko


1 Answers

fgets() is often called in a loop, such as this:

FILE *fp;
char buf[260];// or char *buf, then use malloc - make index size appropriate length for anticipated line len.
fp = fopen("C:\\somedir\\card.txt", "r");
while(fgets(buf, sizeof(buf), fp)) //where sizeof(buf) is the length of   
                                   //line you anticipate reading in.
{
    //do something with buf here;
    //The input of fgets will be NULL as soon 
    //as its input fp has been fully read, then exit the loop  
}
fclose(fp);  

Your statement while((fgets(cards[i][k][j], 3, di->deckFile)) != NULL);
has a couple of issues, one is the ; at the end. It will just loop on this one line, and not give you a chance to do anything with the line that is read before it reads the next one. Also, 3 is probably not the length of line you want to read, is it? 3 is the buffer size that will hold your card data, but the line you read from the file will be longer.

So, in addition to these points, consider the other ideas in the comments, and make changes as indicated.

[EDIT] modified to read a file with "AS3D4C...(52 cards)" 4 lines
It will fill in enough spaces for 4 decks of cards. You can use this to
see how to read in the data. strtok (used before) works only when there
are delimiters, which if you can, I would recommend using instead of
long strings. Hope this helps.
(Note, I used no [mc]alloc()'s in this example.

#include <ansi_c.h>
#define FILENAME "C:\\dev\\play\\cards.txt"

int main()
{
    int i, j;    
    FILE *fp;
    char buf[260];// or char *buf, then use malloc - make index size appropriate length for anticipated line len.
    char *cardTok;
    char cards[208][3]; //4 players, 4 decks, each card is 3 bytes (eg. [A|S|\0], they all need a null termination)

    memset(cards, 0, 208*3);

    fp = fopen(FILENAME, "r");
    j = 0;
    while(fgets(buf, sizeof(buf), fp)) //where buf len is initialized at 260   
                                       //and well over the anticipated 104/line, including \n etc.
    {                          //note, fgets() will read up to n-1 characters and place a \0 at the end
                           //but will stop reading sooner if it sees end of line.
        for(i=0;i<52;i++) //i is card number
        {
            cards[i+j][0] = buf[2*i+0]; 
            cards[i+j][1] = buf[2*i+1];
            cards[i+j][2] = 0;
        }
        j+=52;
    }
    fclose(fp);
}  

My text file looked like this:

9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD3D4SQhKD1H9H3D4SQhKDKD1H9H3D4SQhKD
6C9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD3D4SQhKD1H9H3D4SQhKDKD1H9H3D4SQh
2D9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD3D4SQhKD1H9H3D4SQhKDKD1H9H3D4SQh
3S9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H1H9H3D4SQhKD1H9H3D4SQhKD3D4SQhKD1H9H3D4SQhKDKD1H9H3D4S
like image 149
ryyker Avatar answered Feb 23 '23 03:02

ryyker