#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include <math.h>
#include <unistd.h>
class Dyntext
{
public:
Dyntext(const char *filename);
int nLetters(void);
int nWords(void);
int nSentences(void);
int nTreshold(const int treshold);
int lix(void);
private:
char *theText;
bool in_str(char, const char *);
};
// lookup
char *wordSeparators = " ()\"-,;\t\n\xd"; // \xd är <lf> \n är <cr>
char *sentenceEnds = ".?!:";
// prototyper
void showUsage(const char *argvzero);
// class funktioner
bool Dyntext::in_str(char obj, const char *lookup)
{
int i=0;
do
{
if (obj == lookup[i])
return(true);
i++;
} while (lookup[i] != 0);
return(false);
}
Dyntext::Dyntext(const char *filename)
{
fstream *textFile;
char tempString[13928];
int filepos = 0;
if (strcmp("-", filename) == 0) // read stdin
{
cout << "Skriv text. Avsluta med ett '#'\n";
while ((tempString[filepos] = cin.get()) != '#')
{
filepos++;
}
}
else
{
textFile = new fstream(filename, ios::in);
if (textFile == 0)
{
cerr << "Dyntext: filen hittades inte: (" << filename << ")\n";
exit(true);
}
while ((tempString[filepos] = textFile->get()) != EOF)
{
filepos++;
}
}
tempString[filepos++] = 0;
theText = new char[filepos];
strcpy(theText, tempString);
return;
}
int Dyntext::nLetters(void)
{
int counter=0;
for (int i=0;i<strlen(theText);i++)
{
if(!in_str(theText[i], wordSeparators) && !in_str(theText[i], sentenceEnds))
{
// apostrof är specialfall
if (theText[i] != '\'')
counter++;
}
}
return counter;
}
int Dyntext::nWords(void)
{
int counter = 0;
int i;
for(i=0; i<strlen(theText) - 1;i++)
{
if(in_str(theText[i], wordSeparators)
&& !in_str(theText[i+1], wordSeparators))
counter++;
}
// om den fanns en bokstav i första positionen kommer vi att räkna fel.
// kompensera!
if (!in_str(theText[0], wordSeparators))
counter++;
return counter;
}
int Dyntext::nSentences(void)
{
int counter = 0, i;
for (i=0;i<=strlen(theText);i++)
{
if (in_str(theText[i], sentenceEnds))
counter++;
}
return counter;
}
int Dyntext::nTreshold(const int treshold)
{
int wordlen=0, counter=0, i;
for (i=0;i<strlen(theText);i++)
{
if(in_str(theText[i], wordSeparators) || in_str(theText[i], sentenceEnds))
wordlen=0;
else
if (theText[i] != '\'')
wordlen++;
if ((wordlen == treshold) && (theText[i] != '\''))
counter++;
}
return counter;
}
int Dyntext::lix(void)
{
int sentnum, meansentlen, diffwordsratio;
// undvik ondska om det inte finns meningsslut.
if ((sentnum = nSentences()) == 0)
meansentlen=0;
else
meansentlen = (int) floor(nWords() / sentnum);
diffwordsratio = (int) floor(100*nTreshold(7)/nWords());
return meansentlen + diffwordsratio;
}
int Interactive(char *[]);
int main(int argc, char *argv[])
{
Dyntext *text;
int i=1;
if (argc < 2)
argc = Interactive(argv) + 1;
if (argc == 2 && strncmp("-h",argv[1], 2) == 0)
{
showUsage(argv[0]);
return(false);
}
text = new Dyntext(argv[1]);
cout << "filnamn\t\tbokstäver\tord\tmeningar\tsju+-ord\tlix\n\n";
while(1)
{
cout.form("%7s ", argv[i]) << "\t";
cout << text->nLetters() << "\t\t";
cout << text->nWords() << "\t";
cout << text->nSentences() << "\t\t";
cout << text->nTreshold(7) << "\t\t";
cout << text->lix() << "\n";
if (++i < argc)
text = new Dyntext(argv[i]);
else
break;
}
cout << "\nVäntar 30 sekunder...";
cout.flush();
sleep(30);
return(false);
}
void showUsage(const char *argvzero)
{
cout << "Användning: " << argvzero << " <filnamn1> [filnamn2] ... \n\n";
}
int Interactive(char *argv[])
{
char *buf = new char[256];
char *nexttok;
int i=1;
cout << "(En ensam '-' betyder att programmet läser från stdin)\n";
cout << "Skriv namnet på filerna som skall undersökas med kolon emellan\n$ ";
cin >> buf;
// Om man har en variabel som heter *argv[] får man använda svart magi
// (Gammalt unix-ordspråk) ;-)
if ((nexttok = strtok(buf, ":")) == NULL)
exit(true);
argv[1] = new char[strlen(nexttok)];
strcpy(argv[1], nexttok);
while ((nexttok = strtok(NULL, ":")) != NULL)
{
argv[++i] = new char[strlen(nexttok)];
strcpy(argv[i], nexttok);
}
// vi hittade 'i' tokens
return i;
}