Solved

Stroring file text into array

Posted on 2007-04-02
7
342 Views
Last Modified: 2013-12-14
I am attempting to write a program that inputs lines of text from a file.  The program then displays the total occurrences of each letter, including the apostrophe.  I am having trouble storing the letters into an array.

#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::iostream;
using std::ostream;

#include <string>
using std::getline;

#include<iomanip>
using std::setw;

#include <cstring>
using std::string;

#include <fstream>
using std::fstream;
using std::ifstream;
using std::ofstream;

//Prototype
int readData( char *, char *, int [ ]);

//constant
const char apostrophe = '\'';

int main( )
{
                     // get the total number of EACH LETTER
      int letterTotals[ 28 ] = { 0 };
      int numberOfWords;
      char *wordArrayPtr = { 0 };
      numberOfWords = readData( myInFilePtr, wordArrayPtr, letterTotals );

                     return 0;

} // end of main

int readData( char *fileNamePtr, char *wWordArrayPtr, int letterTotals[ ] )
{
      int wordCount = 1;
      char currentLetter;
      ifstream wMyInFile( fileNamePtr );
      int letterIndex = 0;
      
      wWordArrayPtr = new char;
      //int counter = 0;

      while( !wMyInFile.eof() )
      {
            currentLetter = wMyInFile.peek();      // look at first letter
            //tolower( currentLetter );
            
            cout << " ----> Press Enter to add letter totals of next word to current totals.\n\n";
            getchar();      // used to stop the program before each word

            while( isalpha( currentLetter ) || ( currentLetter == apostrophe ) )
            {      
                  // increment the appropriate index of letterTotals array
                  if (currentLetter >= 'A' && currentLetter <= 'Z')
                  {
                        letterTotals[ int(currentLetter - 'A') + 1 ]++;
                  }
                  else if (currentLetter >='a' && currentLetter <= 'z')
                  {
                        letterTotals[ int(currentLetter - 'a') + 1 ]++;
                  }
                  else if (currentLetter == '\'')
                  {
                        letterTotals[0]++;
                  }
                  //letterTotals[ wordCount ] += wMyInFile.get();
                  //letterTotals[ counter ];
                  cout << "\n\n ---> current letter = " << currentLetter << "\n\n";                  
                  wWordArrayPtr[ wordCount ] += wMyInFile.get( );      // store letter in array
                  currentLetter = wMyInFile.peek();      // look at the next char      

                  /*
                  char letterValue = 96;
                  cout << "letter: " << letterValue << "     ";
                  int index = 0;
                  cout << "letterTotals[ " << index << " ] = " << letterTotals[ index ] << "\n";
                  letterValue = 65;
                  
                  for( index = 1; index < 27; index++ )
                  {
                        cout << "letter: " << letterValue << "     ";
                        cout << "letterTotals[ " << index << " ] = " << letterTotals[ index ] << "\n";
                        letterValue++;
                  }
                  */      
            }
            
            //counter++;

            //wWordArray[ wordCount ] = '\0';
            //letterIndex = 0;
            cout << "\n wordCount before letterTotals = " << wordCount << "\n\n";

            char letterValue = 96;
            cout << "letter: " << letterValue << "     ";
            int index = 0;
            cout << "letterTotals[ " << index << " ] = " << letterTotals[ index ] << "\n";
            letterValue = 65;
                  
            for( index = 1; index < 27; index++ )
            {
                  cout << "letter: " << letterValue << "     ";
                  cout << "letterTotals[ " << index << " ] = " << letterTotals[ index ] << "\n";
                  letterValue++;
            }

            cout << "\n wordCount after letterTotals = " << wordCount << "\n\n";
            
            // !!! -----> the following while is an infinite loop without the break
            while( !isalpha( currentLetter ) && ( currentLetter != apostrophe ) ) // make this an if
            {
                  cout << "\n Entered while...\n";
                  wMyInFile.ignore( 1 );
                  currentLetter = wMyInFile.peek();      // look at the next char
                  break;      // without this break, this while is an infinite loop
            }

            cout << "\n Exited while...\n\n";
            //currentLetter = wMyInFile.peek();      // look at the next char
            wordCount++;
            wWordArrayPtr = new char;
      }
      //cout << "\n Is it reaching this point?\n";
      return wordCount;

} // end of readData
0
Comment
Question by:CharleneS77
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
7 Comments
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 50 total points
ID: 18841656
I didn't check the whole code, so there might be other problems, but I assume your problem originates from this line :

      wWordArrayPtr[ wordCount ] += wMyInFile.get( );      // store letter in array

wWordArrayPtr is an array of char.
wWordArrayPtr[ wordCount ] is the char at position wordCount in the array.
What you do, is add the ASCII value of a character to the ASCII value of another character, forming a new character - that's not what you want to do.

You need an array of strings !

I would suggest to go the C++ way, and use :

      std::string *wWordArrayPtr

And then you can use :

      wWordArrayPtr[ wordCount ] += wMyInFile.get( );      // store letter in array


If there are other problems with the code, please let me know, and I'll take a closer look at the code.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18841660
>> I would suggest to go the C++ way, and use :
>> 
>>       std::string *wWordArrayPtr

Or use a vector like this :

      std::vector<std::string> wWordArrayPtr;

Which is even better !
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 75 total points
ID: 18841684
>>>> wWordArrayPtr[ wordCount ] += wMyInFile.get( );      // store letter in array
That is wrong. You can't use char arrays like string (class) objects.

Why do you want to store the words at all? I don't see that you are using words aor word array?

The whole thing can be made much easier e. g. like that:

    int lpos = 0;
    char line[1024] = { '\0' };
    while (wMyInFile.getline(line, sizeof(line)))
    {
          int n = strlen(line);
          for (int i = 0; i < n; ++i)
          {
                 char c = toupper(line[i]);
                 if (c >= 'A' && c <= 'Z')
                       letterTotals[c - 'A' + 1]++;
                 else if (c == apostrophe)
                        letterTotals[0]++;
                 else if ((unsigned char)c <= ' ')
                 {
                       if (i > lpos + 1)
                             wordCount++;
                      lpos = i;  
                 }
          }
    }            

If using std::string for line buffer (recommedned) it is    

    std::string line;
    while (std::getline(wMyInFile, line))
    {
          int n = line.length();
          ....

Using std::string you easily could add the letters to words. With std::vector you easily could add full words to a dynamic array:        

                 std::string word;
                 std::vector<std::string> wordArr;
                 ...
                             
                       ...
                  if (c >= 'A' && c <= 'Z')
                       letterTotals[c - 'A' + 1]++;
                 else if (c == apostrophe)
                        letterTotals[0]++;
                else if ((unsigned char)c <= ' ')
                 {
                       if (i > lpos + 1)
                      {
                             // wordCount++;   // don't need if using vector
                             wordArr.push_back(word);
                      }
                      lpos = i;  
                      continue;   // next loop cycle if space
                 }
                 word += line[i];   // add original char to word
                   

Regards, Alex
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:CharleneS77
ID: 18854632

>>>else if ((unsigned char)c <= ' ')
                 {
                       if (i > lpos + 1)
                             wordCount++;
                      lpos = i;  
                 }

Can you explain what this is doing?  What is unsigned char used for?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18855995
unsigned char is used in this case to make sure that the values above 127 are not negative. We only want to have this else statement treat the values 0x00 - 0x20. (0x20 is the ASCII value for the space). The characters before the space (0x00 - 0x1F) are all control characters (like a bell, a backspace, a newline, etc.). Take a look at an ASCII table to learn more :

        http://www.asciitable.com/

Now, what is that piece of code doing ?

                 else if ((unsigned char)c <= ' ')       // we only want the control characters and the space
                 {
                       if (i > lpos + 1)                         // lpos is the location of the last such character we found. This checks if we found the next word border (ie. we filter out two consecutive spaces with this check)
                             wordCount++;                   // if so, the word count is included
                      lpos = i;                                    //  we reset lpos to the current location
                 }
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18858056
Infinity, thank you for explanation. It's better than I've had could do  ;-)  (I am on a Kenia trip right now and had no time to answer).

>>>else if ((unsigned char)c <= ' ')

You also could do

   else if (isspace(c))

what checks for whitespace chars like space or tab or linefeed (0x09 - 0xD and 0x20) but not for other controls like 0x00. So personally I prefer  the cast to unsigned char and catch all controls by taking all that are less equal to space (0x20, 32, or ' ').

Regards, Alex
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18858107
>> I am on a Kenia trip right now
Oooh, nice !! And you still take the time to visit EE, while you should be enjoying yourself with the lions :)
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Unable to start eclipse ? 17 173
send messages to whatsapp programatically 2 114
Autosar OS Multicore Share Resources confusion ? 2 195
DCT of  2D array using fftw in c++ 9 131
Here is a helpful source code for C++ Builder programmers that allows you to manage and manipulate HTML content from C++ code, while also handling HTML events like onclick, onmouseover, ... Some objects defined and used in this source include: …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

732 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question