• Support PF! Buy your school textbooks, materials and every day products Here!

C++ Character Processing Algorithm

  • #1

Homework Statement



Hey guys! Thanks for taking the time to help me out, I really appreciate it. I am in my second semester of college, taking my first C++ course, and I had never programmed before this class so I am kind of stuck on a problem. I have almost the entire assignment figured out and I am confident I can get this to work with a bit of guidance so any hints would be wonderful!

The basic idea is that the program will read in data from a text file using fstream and store it as a char. As each character is read in, an isdigit acid test determines if it is a digit from 0-9 and then proceeds to this assignment (if not, then we ignore it):

sum = (10*sum)+ch

Ex.

Code:
char ch;
int sum;
sum= 0;

ch = 3;
sum = 10*0+3 == 3;

ch = 9;
sum = 10*3 + 9 == 39;

ch = 7;
sum = 10*39+7 == 397;

If we read in a '#' we want to print the sum to the data file, and proceed to processing the next string of characters.

For example, in my data file:

@2,89#3,*67
$187,3#%34,72#123#
*3*7*1#2,3,8

The algorithm would process each individual character, assigning its value to sum, then move to the next one until it hits a '\n' or a '#'. The ouput after full processing would look like this:

289
367
1873
3472
123
371
238

Now, I can think of a variety of ways that I could make this work, however, our teacher requires this algorithm to be based on his sample algorithm as well as using the idea of summing the characters together to produce the desired number.

Homework Equations



We are required to use an EOF Loop, process each character individually and use a sum formula to properly output the numbers separated by '#'.


The Attempt at a Solution



Code:
/*  CS 201 - Computer Science 1 
   Program 1 - Version D - Character Filtration
    February 15, 2014  */

#include <iostream>
#include <fstream>
#include <cctype>
using namespace std;

int main () 
{
 /* Variable/Data Type Declarations */  
 char ch;
 int sum;
 ifstream data;
 ofstream out;
    
 /* Input/Output of File Stream Data */
 data.open ("numbers.txt");
 if(not data){
    cout << "Failure to open numbers.txt" << endl;
    system ("pause");
    return 1;}
    
 out.open ("out.txt");
 if(not out){
    cout << "failure to open out.txt" << endl;
    system ("pause");
    return 1;}
 
 sum = 0;      // Initialization of Sum
 data.get(ch); // Priming Read for End-of-File Loop
   
 /* External EOF Loop */
 while(data){   
            
   /* Internal Control Structure and Processing */     
   while((ch !='\n') and data) {  
       
     if(isdigit(ch)){    // All Processing Here
       sum = 10*sum+ch; // Character Sum Assignment
       data.get(ch);   // Update for Inner Loop
       }
            
     if(ch == '#'){  //Decision to Print Sum to File
       out << "The Sum is: " << sum; //Prints Sum to out.txt
       sum = 0; //Resets the Sum
       data.get(ch); //Retrieves next char in istream          
       }
     
   } // Inner Loop
 } // Outer Loop
     

 cout << "Your data has been processed and is available for use. \n " << endl;   
      
 system("pause");
 data.close(); out.close(); // Close Data Files
 return 0;
} // main
I have tried A LOT of different things and I just feel I am missing something really simple. This isn't a difficult problem to program but I think because of the specific conditions we have to apply to the loops per the teacher, it is making it more writing myself out of a corner.

Thanks for any and all input.
 
Last edited:

Answers and Replies

  • #2
lewando
Homework Helper
Gold Member
1,340
134
What is your output? Examining that can provide some clues.
 
  • #3
What is your output? Examining that can provide some clues.
Thanks for your reply and assistance.

Well, I have tried various methods and received different outputs each time. This current code doesn't produce any output (but the codes that produced an output either didn't use sum, or the sum seems to include the characters acsii values and doesn't do the proper conversions). I added a cout statement at the end to let me know that it at least ran through the loops, however, its currently not running through the loops (blank dos window as opposed to cout statement).

Ideally:

it opens the data files

sets sum = 0
then the priming read would grab the first character

go into the End of File loop
while(data)
if that's good, it goes to the "Sentinel" or event-based loop,

while((ch !='\n') and data)

if it's good then it goes into the first test

if(isdigit(ch))
Then it adds the 0-9 digit to my sum formula sum = (10*sum)+ch;
grabs the next digit, etc. until it hits

if(ch == '#')
Then it writes the sum to the output file
Resets the sum
Exits back to the top of inner while loop to make sure ch !='\n'

Then, when it encounters '\n', it exits the inner loop, and the End-of-File loop checks to make
sure we still have data to process.

I could easily use getline and convert the string of characters into the data I need, however, our teacher wants us to use this specific method, so I am a bit hamstrung.
 
  • #4
lewando
Homework Helper
Gold Member
1,340
134
Okay, getting no output is a big clue! Your first character is a '@'. How is your code processing that?
 
  • #5
Okay, getting no output is a big clue! Your first character is a '@'. How is your code processing that?
Great question. Gave me a few ideas.

1) First idea, removed the '@' leaving a leading 2. This didn't change anything that I could tell.

2) I saved my original input file as a copy. The new "numbers.txt" contained only numbers. The program ran successfully (gave me my cout statement) but produced no output. So that tells me that even though I have a problem processing nondigits, I also have a problem producing an output file.

I made some changes to the code, but no luck. I am going to try a couple of things and see if anything changes (in simply processing digits).
 
  • #6
I see a couple of problems now. Going to rewrite some things and let you know if I run into another issue or if I am able to resolve it on my own.
 
  • #7
lewando
Homework Helper
Gold Member
1,340
134
You need to also process the newline '\n' inside your loop. Encountering one is significant. I think you'll get it--good luck!
 
  • #8
So, I came back to it a few minutes ago after taking a break to work on other things and now I am simply getting an output of this:

Code:
The Sum is: 0
The Sum is: 0
So, as I have it written now, it's simply printing the sum's initial value, twice. I thought I understood these loops pretty well, however, things are not occurring in the proper order. I tried a couple of other ideas but this seemed to have the "best output".

I took the comments away temporarily because it was easier to manipulate the code.

Code:
#include <fstream>
#include <iostream>
#include <cctype>
using namespace std;

int main()
{
    char ch;
    int sum;
    ifstream data;
    ofstream out;
    
    data.open("numbers.txt");
    if(not data){
       cout <<"Failure to open numbers.txt" << endl;
       system("pause");
       return 1;}
    
    out.open("out.txt");
    if(not out){
       cout << "Failure to open out.txt" << endl;
       system("pause");
       return 1;}
       
    sum = 0;
    data.get(ch);
    
    while(data)
    {
        while((ch!='\n') and data){
            
            data.get(ch);
            }
    
        if(isdigit(ch)){
            sum = (10*0)+ch;
            data.get(ch);
            }
        
        if(ch == '#' or ch =='\n' ){
            out << "The Sum is: " << sum << endl;
            data.get(ch);
            }
            
    }

    cout << "Processed..." << endl;
    
    system("pause");
    data.close();out.close();
    return 0;
}
 
  • #9
lewando
Homework Helper
Gold Member
1,340
134
When you state what the output is, make sure you state what the input is. And vice versa.

This loop:
Code:
while((ch!='\n') and data){}
seems redundant and superfluous [EDIT: and hazardous] (you are already looping on data and '\n' is being handled inside).

You need to process all characters that you will encounter. I still don't see how you are handling non-digits other than '#' or '\n'.

Try this kind of construct inside the loop:

if ()
{}
else if ()
{}
else if ()
{}
else
{}

That should enable you to handle all character cases and do only one {} with each pass of the loop. You should be reading only one new character with each pass of the loop.
 
Last edited:
  • #10
33,186
4,872
Where is this "not" defined?
Code:
if([B]not[/B] data){
       cout <<"Failure to open numbers.txt" << endl;
       system("pause");
       return 1;}
I get what it's doing, but I haven't seen it before. I searched on cplusplus.com and didn't find it listed as an operator.
 
  • #11
Where is this "not" defined?
Code:
if([B]not[/B] data){
       cout <<"Failure to open numbers.txt" << endl;
       system("pause");
       return 1;}
I get what it's doing, but I haven't seen it before. I searched on cplusplus.com and didn't find it listed as an operator.
Hey Mark! The "not" is a boolean value for "!". Another way to write it would have been !data.

However, most of this code is straight from my teacher's algorithm that are strictly required to adhere to. If I was allowed to write my own code, I would be done by now.

However, I scrapped the original project and re-entered his algorithm and trying to implement the loops again. We aren't allowed to change any test conditions or add anything else other than the necessary if statements to satisfy the conditions of the loop.
 
  • #12
When you state what the output is, make sure you state what the input is. And vice versa.

This loop:
Code:
while((ch!='\n') and data){}
seems redundant and superfluous [EDIT: and hazardous] (you are already looping on data and '\n' is being handled inside).

You need to process all characters that you will encounter. I still don't see how you are handling non-digits other than '#' or '\n'.

Try this kind of construct inside the loop:

if ()
{}
else if ()
{}
else if ()
{}
else
{}

That should enable you to handle all character cases and do only one {} with each pass of the loop. You should be reading only one new character with each pass of the loop.
Lewando, that solution makes perfect sense, however, I am required to use my teacher's algorithm.

The
Code:
while((ch !='\n') and data)
is his piece of code and I am not allowed to change any of the test conditions. I reread the chapter on loops and nested if-else statements but I guess I am still not quite understanding how it works.

I have rewritten my program, however, I am still getting incorrect output.

Input:

Code:
@2,89#3,*67
$187,3#%34,72#123#
*3*7*1#2,3,8
Output:
Code:
#
####8
Here is my new code:

Code:
/* Character Filtration Algorithm */

#include <fstream>
#include <iostream>
#include <cctype>
using namespace std;

int main()
{
  ifstream data;
  ofstream out;
  char ch;
  int n, sum; 

  data.open("numbers.txt"); // Open Input Data File
  if (not data){
      cout << "Can't open numbers.txt" << endl;
      system ("pause");
      return 1;}

  out.open("out.txt"); // Generate Output Data File
  if (not out){
      cout << "Can't open out.txt" << endl;
      system ("pause");
     return 1;}

  data.get(ch); // Priming Read for End-of-File Loop
  while (data){ // End-of-File Loop
     sum = 0;

     while((ch != '\n') && data){
                    
         if(isdigit(ch)){ // Test for digit
            sum = sum * 10+ch; // Sum Assignment
            }
                 
         if((ch == '#') && data){ // Test for '#'
            out.put(ch);
            }
      
      data.get(ch); // Next Character
           
     } // Inner Loop
  
     if (sum > 0){ // Test for Sum
        out.put(ch);
        }

    data.get(ch); // Next Character
  } // End-of-File Loop

  cout << "Program Successful " << endl;

system ("pause");
data.close(); out.close(); // Close Data Files
return 0;
}
 
  • #13
33,186
4,872
Hey Mark! The "not" is a boolean value for "!". Another way to write it would have been !data.
Right, I get that. My question was where is this defined? I haven't seen it before. It wasn't part of C++ a while back, and I wonder if they changed the language to include "not" and "and" and so forth. As I said before, I looked on the cplusplus.com site and didn't find any mention of these operators.
 
  • #14
AlephZero
Science Advisor
Homework Helper
6,994
291
My question was where is this defined?
http://en.cppreference.com/w/cpp/keyword
Note that and, bitor, or, xor, compl, bitand, and_eq, or_eq, xor_eq, not, and not_eq (along with the digraphs <%, %>, <:, :>, %:, and %:%:) provide an alternative way to represent standard tokens.
 
  • #15
lewando
Homework Helper
Gold Member
1,340
134
... that solution makes perfect sense, however, I am required to use my teacher's algorithm.

The
Code:
while((ch !='\n') and data)
is his piece of code and I am not allowed to change any of the test conditions.
If you are constrained, then I suggest adding some "loop exit code" when you break out of the loop (as a result of a '\n' or !data). You are already using "loop entry code" (the initial priming of ch), so give it a try.
 
  • #16
Yo, Lewando! Thanks for your all of your help. I figured out my issue. I wasn't using an ACSII character conversion formula
Code:
 (ch-'0')
.

It is working properly now. Here is the final code in case anyone is curious (I need to tidy the style up a bit):

Code:
/* Character Filtration Algorithm */

#include <fstream>
#include <iostream>
#include <cctype>
using namespace std;

int main()
{
  ifstream data;
  ofstream out;
  char ch;
  int sum; 

  data.open("numbers.txt"); // Open Input Data File
  if (not data){
      cout << "Can't open numbers.txt" << endl;
      system ("pause");
      return 1;}

  out.open("out.txt"); // Generate Output Data File
  if (not out){
      cout << "Can't open out.txt" << endl;
      system ("pause");
     return 1;}

  data.get(ch); // Priming Read for End-of-File Loop
  while (data){ // End-of-File Loop
     sum = 0;

     while((ch != '\n') and data){
                    
         if(isdigit(ch)){ // Test for digit
            sum = (10*sum)+(ch-'0'); // Sum Assignment
            }
                 
         if((ch == '#')){ // Test for '#'
            out << sum << endl;
            sum = 0;
            }
      
     data.get(ch); // Next Character        
     } // Inner Loop
  
     if (sum > 0){ // Test for Sum
        out << sum << endl;
        }

  data.get(ch); 
  } // End-of-File Loop

  cout << "Program Successful " << endl;

system ("pause");
data.close(); out.close(); // Close Data Files
return 0;
}
 
Last edited:

Related Threads for: C++ Character Processing Algorithm

Replies
8
Views
3K
Replies
1
Views
3K
Replies
2
Views
1K
Replies
15
Views
3K
Replies
12
Views
864
Replies
1
Views
1K
Replies
8
Views
7K
Replies
1
Views
939
Top