0

In C++ I'm trying to completely read files, char by char, using stdio.h (fopen, getc, etc). I have done a program that creates an explorer window and count the letters (and the number of Byte) inside a selected file. It seems to work properly for .txt files, but with other file formats it doesn't work. Can somebody explain why and how to fix it? Is it possible to determinate by program also the size on disk?

The 3 source code:

Main code:

#include "OpenFileDialog.h"
#include <stdio.h>
#include <stdlib.h>

int main(void){

    OpenFileDialog* openFileDialog1 = new OpenFileDialog();
    openFileDialog1->FilterIndex = 1;
    openFileDialog1->Flags |= OFN_SHOWHELP;
    openFileDialog1->InitialDir = (TCHAR*)("C:\\Users\\Luca\\Documents");
    openFileDialog1->Title = (TCHAR*)("Open Text File");
    long long int number=0;

    if (openFileDialog1->ShowDialog())
    {
        //MessageBox(0, openFileDialog1->FileName, "File selected",MB_OK | MB_ICONINFORMATION);
    }

    FILE * pFile;
    char c;
    int eofnbr=0;
    int charnbr[256];
    int otherschar=0;
    char messageString1[2000];
    char catString[200];
    memset(charnbr,0,sizeof(messageString1));
    memset(charnbr,0,sizeof(charnbr));
    pFile = fopen(openFileDialog1->FileName,"r");
    if (pFile==NULL){
        return -1;
    }
    else{
        int eofflag=0;
        do{
            do{
                c = getc (pFile);
                if((c>=0)&&(c<=255)){
                    charnbr[c]=charnbr[c]+1;
                }
                else
                    otherschar++;
                if(c==EOF){
                    eofnbr++;
                }
                number++;
            } while (c != EOF);
            eofflag=feof(pFile);
        } while(eofflag==0);    


        fclose (pFile);
        for(int i=0;i<256;i=i+8){
            sprintf(catString,"%d = %d\t%d = %d\t%d = %d\t%d = %d\t%d = %d\t%d = %d\t%d = %d\t%d = %d\n",i,charnbr[i],i+1,charnbr[i+1],i+2,charnbr[i+2],i+3,charnbr[i+3],i+4,charnbr[i+4],i+5,charnbr[i+5],i+6,charnbr[i+6],i+7,charnbr[i+7]);
            strcat(messageString1,catString);
        }
        sprintf(catString,"others = %d\t EOF = %d\t\t%d   Byte\n ",otherschar,eofnbr, number);
        strcat(messageString1,catString);
    }
    MessageBox(0, messageString1, "File selected",MB_OK | MB_ICONINFORMATION);

    return 0;
}

Explorer functions:

#include "OpenFileDialog.h"

OpenFileDialog::OpenFileDialog(void)
{
    this->DefaultExtension = 0;
    this->FileName = new TCHAR[MAX_PATH];
    this->Filter = 0;
    this->FilterIndex = 0;
    this->Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    this->InitialDir = 0;
    this->Owner = 0;
    this->Title = 0;
}

bool OpenFileDialog::ShowDialog()
{
    OPENFILENAME ofn ;

    TCHAR* explorerFolder= this->InitialDir;

    ZeroMemory(&ofn, sizeof(ofn));


    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = this->Owner;
    ofn.lpstrDefExt = this->DefaultExtension;
    ofn.lpstrFile = this->FileName;
    ofn.lpstrFile[0] = '\0';
    //ofn.lpstrFile = explorerFolder;
    ofn.nMaxFile = MAX_PATH;
    ofn.lpstrFilter = this->Filter;
    ofn.nFilterIndex = this->FilterIndex;
    ofn.lpstrInitialDir = explorerFolder;
    //ofn.lpstrInitialDir = NULL;
    ofn.lpstrTitle = this->Title;
    ofn.Flags = this->Flags;

    GetOpenFileName(&ofn);


    if (_tcslen(this->FileName) == 0) return false;

    return true;
}

Explorer library:

#pragma once

#include <Windows.h>
#include <Commdlg.h>
#include <tchar.h>

class OpenFileDialog
{
public:
    OpenFileDialog(void);

    TCHAR* DefaultExtension;
    TCHAR* FileName;
    TCHAR* Filter;
    int FilterIndex;
    int Flags;
    TCHAR* InitialDir;
    HWND Owner;
    TCHAR* Title;

    bool ShowDialog();
};

Image test with .txt

Image test with .pdf

Luckk93
  • 3
  • 3
  • 1
    There are many easier ways to do this in C++. Look at `std::string` and the `iostream` library. – user4581301 Sep 13 '17 at 00:17
  • 1
    The most likely reason is because of the archaic "feature" of your operating system that creates an artificial distinction between text and binary files. Reading the hex `0x1A` character from a file opened as a text file results in an end-of-file condition, even if it's the first character in a gigabyte-long file; and most hex `0x0D` characters gets discarded. To actually open the file in binary mode, use "rb" instead of "r"; in order read the actual file, instead of some mangled interpretation of it. – Sam Varshavchik Sep 13 '17 at 00:17
  • Why are you using `fopen()`, `getc()`, etc in C++? Those are C functions. Use `std::ifstream` instead in C++. At the very least, you have to open the files in binary mode, but you are opening them in text mode instead. On a side note, your `TCHAR*` type-casts are wrong, use the `TEXT()` macro instead: `InitialDir = TEXT("C:\\Users\\Luca\\Documents"); Title = TEXT("Open Text File");` – Remy Lebeau Sep 13 '17 at 00:38

0 Answers0