Thread: Multiple Pages in a Txt File

  1. #1
    Registered User
    Join Date
    Jun 2007
    Location
    Qatar
    Posts
    39

    Multiple Pages in a Txt File

    Text file cannot behave as pages.But in my program i m in need of different pages of a document.The only format allowed in C++ is txt.So how i can access this data from the text file in terms of pages ?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Read the file in groups of 50 lines, or however many lines you consider to be on a page.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2007
    Location
    Qatar
    Posts
    39
    But how i can program it in C++

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    I've no idea - what do you think?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jun 2007
    Location
    Qatar
    Posts
    39
    i have in my mind to read the characters of the document. And when i need to jump on page lets say to 29 i just multiply 29 by the number of characters in (50 lines).But here the problem is storing so many characters uselessly.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > But here the problem is storing so many characters uselessly.
    How much memory does your system have - MB or GB ?
    How big are your text files - KB ?

    Reading the whole file into an array (or vector) of lines makes for very simple code.

    You can use a lot less memory, but the code complexity goes up, and the performance gets worse.

    In the end, it's your choice.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Why not make an index of file pointers to pages in the beginning of the file?
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  8. #8
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    i have in my mind to read the characters of the document.
    Why read characters when you need 50 lines? Read lines instead. See the std::getline() function.

  9. #9
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    The code complexity is high, the performance is also high. I just wanted to build something stupid.

    Do not use this if you don't understand it (windows-specific code).
    Code:
    #define PAGE_INITIALIZED 0x2A3B4C
    
    typedef struct _INDEX_ITEM{
        DWORD dwSize;
        char* lpData;
    } INDEX_ITEM;
    
    typedef struct _PAGE_INDEX{
        DWORD dwInit;
        HANDLE hHeap;
        DWORD dwPages;
        INDEX_ITEM* lpPages;
    } PAGE_INDEX;
    
    //this must be called first
    bool PG_Init(PAGE_INDEX* lpIndex){
        if(!lpIndex){ return false; }
        lpIndex->dwPages=0;
        lpIndex->lpPages=NULL;
        lpIndex->hHeap=HeapCreate(0,0x1000,0);
        if(!lpIndex->hHeap){
            return false;
        }
        lpIndex->dwInit=PAGE_INITIALIZED;
        return true;
    }
    
    //this must be called if you're done with it
    void PG_Deinit(PAGE_INDEX* lpIndex){
        if(!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED){ return; }
        for(int i=0;i<lpIndex->dwPages;i++){
            if(lpIndex->lpPages[i].dwSize&&lpIndex->lpPages[i].lpData){
                HeapFree(lpIndex->hHeap,0,lpIndex->lpPages[i].lpData);
            }
        }
        HeapFree(lpIndex->hHeap,0,lpIndex->lpPages);
        HeapDestroy(lpIndex->hHeap);
        lpIndex->dwPages=0;
        lpIndex->lpPages=NULL;
        lpIndex->dwInit=0;
    }
    
    //creates a new page and returns its ID
    int PG_CreatePage(PAGE_INDEX* lpIndex){
        if(!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED){ return -1; }
        if(!lpIndex->lpPages){
            lpIndex->lpPages=(INDEX_ITEM*)HeapAlloc(lpIndex->hHeap,HEAP_ZERO_MEMORY,32*sizeof(INDEX_ITEM));
        }
        else if(!(lpIndex->dwPages&#37;32)){
            lpIndex->lpPages=(INDEX_ITEM*)HeapReAlloc(lpIndex->hHeap,HEAP_ZERO_MEMORY,lpIndex->lpPages,
                (((lpIndex->dwPages>>5)+1)<<5)*sizeof(INDEX_ITEM));
        }
        lpIndex->lpPages[lpIndex->dwPages].dwSize=0;
        lpIndex->lpPages[lpIndex->dwPages].lpData=NULL;
        lpIndex->dwPages++;
        return lpIndex->dwPages-1;
    }
    
    //you can set binary data to a page with this
    bool PG_SetPageRawData(PAGE_INDEX* lpIndex,DWORD dwId,char* lpData,DWORD dwSize){
        char* lpBkupData;
        INDEX_ITEM* lpCur;
        if(!lpData||!dwSize||!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED||
            dwId>=lpIndex->dwPages){ return false; }
        lpCur=(&(lpIndex->lpPages[dwId]));
        if(dwSize>lpCur->dwSize){
            if(!lpCur->lpData){
                lpCur->lpData=(char*)HeapAlloc(lpIndex->hHeap,HEAP_ZERO_MEMORY,dwSize);
                if(!lpCur->lpData){
                    return false;
                }
                lpCur->dwSize=dwSize;
            }
            else{
                lpBkupData=lpCur->lpData;
                lpCur->lpData=(char*)HeapReAlloc(lpIndex->hHeap,HEAP_ZERO_MEMORY,lpCur->lpData,dwSize);
                if(!lpCur->lpData){
                    lpCur->lpData=lpBkupData;
                    return false;
                }
                lpCur->dwSize=dwSize;
            }
        }
        for(int i=0;i<dwSize;i++){
            lpCur->lpData[i]=lpData[i];
        }
        return true;
    }
    
    //you can assign text to a page with this
    bool PG_SetPageText(PAGE_INDEX* lpIndex,DWORD dwId,char* lpData){
        int len;
        for(len=0;lpData[len];len++);
        return PG_SetPageRawData(lpIndex,dwId,lpData,len+1);
    }
    
    //gets the text buffer size, use when copying the buffer data to a new buffer
    DWORD PG_GetPageBufferSize(PAGE_INDEX* lpIndex,DWORD dwId){
        if(!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED){ return 0; }
        return lpIndex->lpPages[dwId].dwSize;
    }
    
    //get the pointer to the specified page's buffer
    char* PG_GetPageBuffer(PAGE_INDEX* lpIndex,DWORD dwId){
        if(!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED){ return 0; }
        return lpIndex->lpPages[dwId].lpData;
    }
    
    //get the number of pages
    DWORD PG_GetNumOfPages(PAGE_INDEX* lpIndex){
        if(!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED){ return 0; }
        return lpIndex->dwPages;
    }
    
    //save it all to a file
    bool PG_SaveToFile(PAGE_INDEX* lpIndex,char* lpFileName){
        HANDLE hFile;
        DWORD dwWritten,dwLine,dwZero=0;
        if(!lpIndex||!lpFileName||lpIndex->dwInit!=PAGE_INITIALIZED){ return false; }
        hFile=CreateFileA(lpFileName,GENERIC_WRITE,7,0,CREATE_ALWAYS,0,0);
        if(hFile==INVALID_HANDLE_VALUE){
            return false;
        }
        WriteFile(hFile,&(lpIndex->dwPages),4,&dwWritten,0);
        dwLine=4+lpIndex->dwPages*8;
        for(int i=0;i<lpIndex->dwPages;i++){
            WriteFile(hFile,&(lpIndex->lpPages[i].dwSize),4,&dwWritten,0);
            WriteFile(hFile,&dwLine,4,&dwWritten,0);
            dwLine+=lpIndex->lpPages[i].dwSize;
        }
        for(int i=0;i<lpIndex->dwPages;i++){
            WriteFile(hFile,lpIndex->lpPages[i].lpData,lpIndex->lpPages[i].dwSize,&dwWritten,0);
        }
        CloseHandle(hFile);
        return true;
    }
    
    //load it all from a file
    bool PG_LoadFromFile(PAGE_INDEX* lpIndex,char* lpFileName){
        HANDLE hFile;
        DWORD dwRead,dwPointer,dwNewPointer,dwPages;
        if(!lpIndex||lpIndex->dwInit!=PAGE_INITIALIZED){ return false; }
        hFile=CreateFileA(lpFileName,GENERIC_READ,7,0,OPEN_ALWAYS,0,0);
        if(hFile==INVALID_HANDLE_VALUE){
            return false;
        }
        ReadFile(hFile,&dwPages,4,&dwRead,0);
        for(int i=0;i<dwPages;i++){
            PG_CreatePage(lpIndex);
            ReadFile(hFile,&(lpIndex->lpPages[i].dwSize),4,&dwRead,0);
            lpIndex->lpPages[i].lpData=(char*)HeapAlloc(lpIndex->hHeap,0,lpIndex->lpPages[i].dwSize);
            ReadFile(hFile,&dwNewPointer,4,&dwRead,0);
            dwPointer=SetFilePointer(hFile,0,0,FILE_CURRENT);
            SetFilePointer(hFile,dwNewPointer,0,FILE_BEGIN);
            ReadFile(hFile,lpIndex->lpPages[i].lpData,lpIndex->lpPages[i].dwSize,&dwRead,0);
            SetFilePointer(hFile,dwPointer,0,FILE_BEGIN);
        }
        CloseHandle(hFile);
        return true;
    }
    An example to use:
    Code:
    char* buf;
    DWORD dwPages;
    PAGE_INDEX pgi;
    if(PG_Init(&pgi)){
        PG_SetPageText(&pgi,PG_CreatePage(&pgi),"This is on the page 1");
        PG_SetPageText(&pgi,PG_CreatePage(&pgi),"This is on the page 2");
        PG_SetPageText(&pgi,PG_CreatePage(&pgi),"This is on the page 3");
        PG_SaveToFile(&pgi,"test.txt");
        PG_Deinit(&pgi);
    }
    if(PG_Init(&pgi)){
        PG_LoadFromFile(&pgi,"test.txt");
        dwPages=PG_GetNumOfPages(&pgi);
        for(int i=0;i<dwPages;i++){
            buf=PG_GetPageBuffer(&pgi,i);
            if(buf){
                MessageBox(0,buf,"Contents of a page",MB_OK);
            }
        }
        PG_Deinit(&pgi);
    }
    Actually I think I should retire from trying to confuse beginners...
    Last edited by maxorator; 08-24-2007 at 09:21 AM.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Or in nice standard C++, the bulk of the interesting work is about 10 lines.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by Salem View Post
    Or in nice standard C++, the bulk of the interesting work is about 10 lines.
    Yeah. I kind of wonder about people that think it's so uber 1337 to use the Windows API for no apparent reason.

  12. #12
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Quote Originally Posted by MacGyver View Post
    Yeah. I kind of wonder about people that think it's so uber 1337 to use the Windows API for no apparent reason.
    Why do it with CRT if I can waste time with WinAPI?

    Actually, why should I use CRT if the CRT eventually calls WinAPI functions? I don't really care about how much time it takes me to complete the code. I'm bored anyway. If I have so much time in my hand why can't I do something stupid that runs fast?
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  13. #13
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    So how much faster is it? And how many bugs does it have?

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by cpjust View Post
    So how much faster is it? And how many bugs does it have?
    For one thing, it's not at all guaranteed that the C-library is slower: Consider this:
    Code:
         FILE *f;
         f = fopen("a.txt", "w");
         for(i = 0; i < 10000; i++) 
            fputc(f, '*');
    -----
         HANDLE h;
         char data = '*';
         DWORD dwritten;
         h = CreateFileA("a.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
         for(i = 0; i < 10000; i++) 
            WriteFile(h, &data, 1, &dwritten, NULL);
    Since a file is buffered, you'd have to add code to buffer yourself (and thus just replicating the efforts in the C-library). The WriteFile may well be buffered, but only the other side of the system-call, which means that it's costing a user->kernel->user transition (and those are noticable in all processors, particularly x86) - compare that with a function that just stuffs a character into a buffer and checks if the buffer is full yet.

    --
    Mats

  15. #15
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    If you replicate the efforts of C-library then you will get faster results. Buffered stuff:
    Code:
    char* lpData=new char[4096];
    DWORD dwCount=0,dwWritten;
    HANDLE hFile=CreateFileA("a.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,0, 0);
    if(hFile!=INVALID_HANDLE_VALUE){
        for(int i=0;i<10000;i++){
            if(dwCount>=4096){
                WriteFile(hFile,lpData,dwCount,&dwWritten,0);
                dwCount=0;
            }
            lpData[dwCount]='*';
            dwCount++;
        }
        WriteFile(hFile,lpData,dwCount,&dwWritten,0);
        CloseHandle(hFile);
    }
    delete[] lpData;
    "The Internet treats censorship as damage and routes around it." - John Gilmore

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Data Structure Eror
    By prominababy in forum C Programming
    Replies: 3
    Last Post: 01-06-2009, 09:35 AM
  2. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM