![]() |
| | #1 |
| Registered User Join Date: Apr 2003
Posts: 33
| Unix/C++ problem Code: //*********************************************************************************************
//
// This program finds a word or phrase input by the user in a file and outputs the lines of
// the file and the number of occurances.
//
//*********************************************************************************************
#include <iostream.h>
#include <fstream.h>
typedef char characterString[45];
char SENTINAL = '*';
int compairText(characterString input, int x, characterString target, int y, int numberOfCharacters);
void convertText(characterString input);
int main()
{
characterString input; //input string
characterString target; //target string
int numberOfCharacters = -1; //number of characters in the target string
int lineNumber = 1; //number of lines
int numberOfMatches = 0; //keeps the number of matches found
ifstream infile; //input file
ofstream outfile; //output file
infile.open("hw02.dat");
outfile.open("Output.dat");
for(int i = 0; i < 45; i++)
target[i] = SENTINAL; //initilizes the target string to *
cout << "Enter the word to search for: " << endl;
cin >> target;
convertText(target);
for(int j = 0; j < 45; j++) //finds the number of characters in the target string
{
if(target[j] != SENTINAL)
numberOfCharacters++;
}
cout << "Line Number \t Number of Matches" << endl;
while(infile.peek() != EOF)
{
infile.getline(input, 50, '\n');
convertText(input);
for(int k = 0; k < 45; k++) //traverses the input string
{
if(target[0] == input[k])
if(compairText(input, k, target, 0, numberOfCharacters))
{
numberOfMatches++;
k += numberOfCharacters;
}
}
cout << lineNumber << "\t\t\t" << numberOfMatches << endl;
outfile << lineNumber << "\t\t\t" << numberOfMatches << endl;
lineNumber++;
numberOfMatches = 0;
}
infile.close();
outfile.close();
return 0;
}
//*********************************************************************************************
int compairText(characterString input, int x, characterString target, int y, int z)
{
if(z == 0)
return 1;
else
{
if(input[x] != target[y])
return 0;
if(input[x] == target[y])
if(compairText(input, (x+1), target, (y+1), (z-1)))
return 1;
}
}
//*********************************************************************************************
void convertText(characterString x)
{
for(int i = 0; i < 45; i++)
if(x[i] >= 65 && x[i] <= 90)
x[i] += 32;
}
-Bill P.S. sorry about the tags haven't learned how to use them yet, yes i know i know i'm a n00b Last edited by Maverik; 04-11-2003 at 03:03 PM. |
| Maverik is offline |
| | #2 | |
| Registered User Join Date: Mar 2003
Posts: 3,898
| Re: Unix/C++ problem Quote:
gg | |
| Codeplug is offline |
| | #3 |
| Registered User Join Date: Mar 2003
Posts: 3,898
| - compairText() should have a "return 0;" at the end - getline() could cause a buffer overrun since your characterString has only 45 chars and you are asking for up to 50 - your code won't work if you process a file that has >45 chars in a single line - your code has a bug where the following file isn't processed correctly when looking for "hello" (I'll let you figure it out): - you don't need any of that SENTINAL stuff since strings are already terminated with '\0' (not a bug though) Code: hello world HELLO world gg |
| Codeplug is offline |
| | #4 |
| Registered User Join Date: Apr 2003
Posts: 33
| It's not consistanely off by one number or a number, it finds the correct number of occurences if the word does occur but it gives like the nujber 3, 4 or 2 if there aren't anything on the lines. However i am going to try what you posted about the second time and hopefully that will fix it. Thanks for the insite. -Bill |
| Maverik is offline |
| | #5 | |
| Registered User Join Date: Apr 2003
Posts: 33
| Quote:
Code: while(infile).....; while(infile.peek() != EOF)......; while(!EOF)......; and even do while(infile)..........; -Bill Last edited by Maverik; 04-12-2003 at 04:20 PM. | |
| Maverik is offline |
| | #6 |
| Registered User Join Date: Apr 2003
Posts: 33
| ok i got it working now. I think the problem was with the getline function. It would read up to 50 characters or to a newline which ever was first. And since the file is fixed so that each line in the file has no more than 45 characters. I should have told you guys that before hand and that would have made it all the difference. But thanks for the help.-Bill |
| Maverik is offline |
| | #7 |
| Registered User Join Date: Apr 2003
Posts: 33
| And here is the code if you want it Code: #include <iostream.h>
#include <fstream.h>
#include <cstring>
typedef char characterString[45];
int compairText(characterString input, int x, characterString target, int y, int numberOfCharacters);
void convertText(characterString input);
int main()
{
characterString input; //input string
characterString target; //target string
int numberOfCharacters = -1; //number of characters in the target string
int lineNumber = 1; //number of lines
int numberOfMatches = 0; //keeps the number of matches found
ifstream infile; //input file
ofstream outfile; //output file
infile.open("hw02.dat");
outfile.open("Output.dat");
cout << "Enter the word to search for: " << endl;
cin >> target;
convertText(target);
numberOfCharacters = strlen(target);
cout << "Line Number \t Number of Matches" << endl;
while(infile.peek() != EOF)
{
infile.getline(input, 50, '\n');
convertText(input);
for(int k = 0; k < 45; k++) //traverses the input string
{
if(target[0] == input[k])
if(compairText(input, k, target, 0, numberOfCharacters))
{
numberOfMatches++;
k = k + numberOfCharacters - 1;
}
}
cout << lineNumber << "\t\t\t" << numberOfMatches << endl;
outfile << lineNumber << "\t\t\t" << numberOfMatches << endl;
lineNumber++;
numberOfMatches = 0;
}
infile.close();
outfile.close();
return 0;
}
//*********************************************************************************************
int compairText(characterString input, int x, characterString target, int y, int z)
{
if(z == 0)
return 1;
else
{
if(input[x] != target[y])
return 0;
else if(input[x] == target[y])
if(compairText(input, (x+1), target, (y+1), (z-1)))
return 1;
}
return 0;
}
//*********************************************************************************************
void convertText(characterString x)
{
for(int i = 0; i < 45; i++)
if(x[i] >= 65 && x[i] <= 90)
x[i] += 32;
}
|
| Maverik is offline |
| | #8 |
| Registered User Join Date: Mar 2003
Posts: 3,898
| You are still using telling getline() that you have 50 chars, when you only have 45......bad. gg |
| Codeplug is offline |
| | #9 |
| Registered User Join Date: Feb 2003
Posts: 490
| Are you aware that your program (even after your changes) still doesn't work correctly? It runs, and it gives output, but that output is wrong. It is reporting occurrences of the target string on lines where it does not exist. First, as codeplug pointed out, you have an inconsistency between the defined length of your characterString variable and the length of the input lines you are reading in. This is definitely a problem. And, as a matter of good form, you should avoid having these "magic numbers" floating around in your code -- makes it hard to debug and hard to modify later on should that become necessary. Instead, define a constant and use that constant in the body of the program to define array sizes, limits for "while" statements, etc. As an example, I defined a constant MAXSTRING in the code posted below. Second, while debugging, you should learn to use extra print statements to help figure out where the program is going wrong. Below is a modified version of your code which STILL doesn't work correctly, but if you study its screen output you should be able to figure out what's going wrong. Maybe you have been testing with a file that makes it appear that the program works. Just in case, I'm also attaching the file I have been using to test your program. Use it, and search for the word "release" & you will see that your code reports occurrences EVEN ON BLANK LINES. Anyway, check the output of this version. There is still one error remaining that can cause the output to be completely inaccurate(as it does with my input file). Using the step by step output you should be able to find it. Code: #include <iostream.h>
#include <fstream.h>
#include <cstring>
#include <stdio.h> //for getchar() (to pause while debugging)
#define MAXSTRING 50 // constant to define maximum input string length throughout the program
typedef char characterString[MAXSTRING+1]; //allowing space for null byte
int compairText(characterString input, int x, characterString target, int y, int numberOfCharacters);
void convertText(characterString input);
int main()
{
characterString input; //input string
characterString target; //target string
int numberOfCharacters = -1; //number of characters in the target string
int lineNumber = 1; //number of lines
int numberOfMatches = 0; //keeps the number of matches found
ifstream infile; //input file
ofstream outfile; //output file
infile.open("hw02.dat");
outfile.open("Output.dat");
cout << "Enter the word to search for: " << endl;
cin >> target;
convertText(target);
numberOfCharacters = strlen(target);
cout << "Line Number \t Number of Matches" << endl;
while(infile.peek() != EOF)
{
cout << "entering while loop; numberOfMatches = " << numberOfMatches << endl;
infile.getline(input, MAXSTRING+1, '\n');
cout << input << endl; //debug
convertText(input);
cout << input << endl; //debug
// in the next line I reduced the upper limit of the search - no point checking the
// last few letters if there are fewer than numberOfCharacters remaining in the string
for(int k = 0; k < MAXSTRING-numberOfCharacters+1; k++) //traverses the input string
{
cout << "now testing input[" << k << "]: contents = " << input[k] << endl; // debug
if(target[0] == input[k])
{ cout << "entered first \"if\", numberOfMatches =" << numberOfMatches << endl;//debug
if(compairText(input, k, target, 0, numberOfCharacters))
{
cout << "after successful compairText, numberOfMatches ="
<< numberOfMatches << endl; //debug
numberOfMatches++;
cout << "incremented numberOfMatches to " << numberOfMatches << endl;//debug
k = k + numberOfCharacters - 1;
}
}
}
cout << "finished traversing the string" << endl;
cout << lineNumber << "\t\t\t" << numberOfMatches << endl;
outfile << lineNumber << "\t\t\t" << numberOfMatches << endl;
lineNumber++;
numberOfMatches = 0;
cout << "numberOfMatches reset to " << numberOfMatches << endl; //debug
cout << "press <enter> to continue" << endl; //debug
getchar(); //debug
}
infile.close();
outfile.close();
return 0;
}
// ****************************************************
int compairText(characterString input, int x, characterString target, int y, int z)
{
if(z == 0)
return 1;
else
{
if(input[x] != target[y])
return 0;
else if(input[x] == target[y])
if(compairText(input, (x+1), target, (y+1), (z-1)))
return 1;
}
return 0;
}
// ****************************************************
void convertText(characterString x)
{
for(int i = 0; i < MAXSTRING; i++)
if(x[i] >= 65 && x[i] <= 90)
x[i] += 32;
}
1-2-3 Release 5 for Windows Product Updates (READM **CONTENTS** Updating Release 4 Worksheet Files to Release 5 Install Information for Upgraders Installing on Computers with Multiple Configuratio Server and Distribution Install 3. Windows and Available Memory 4. Charting Information for Upgraders 5. Printing Performance Information Printer Drivers and Devices Print Resolution 6. DataLens and ODBC Drivers ODBC Drivers Environment Variables 7. Version Manager 8. Solver 9. Command-Line Parameters 10. Corrections to the Documentation Macros Help Help for 1-2-3 Messages The Guided Tour 11. Font Usage Font Mapping Font Performance Tips Removing ATM 12. Map Performance Information Finding the Correct Map Type Map Resolution Map Macros Maps and Lotus Approach 13. Compatibility Working with .WK1 Files Working with Excel Files Working with dBASE Files 14. Using 1-2-3 with OS/2 **1. UPDATING RELEASE 4 WORKSHEET FILES TO RELEASE Last edited by R.Stiltskin; 04-13-2003 at 04:08 PM. |
| R.Stiltskin is offline |
| | #10 |
| Registered User Join Date: Feb 2003
Posts: 490
| By the way, I don't know why, but when I compile this code in Unix using the CC compiler, it compiles OK but when it runs it only processes the first line of input and then exits the program. But when I compile it with the g++ compiler, it behaves the same as it does with MSVC++ 6.0 -- output is still wrong because of the remaining logic error, but it does process the entire file. Anybody know the reason for this discrepancy? Another getline problem maybe? |
| R.Stiltskin is offline |
| | #11 |
| Registered User Join Date: Apr 2003
Posts: 33
| C++ logic error ok this is the same program as before. It searches a file for a word and find the number of occurences in each line. I got rid of the recursion. No i am having problems with the Function that finds the numbner of occurences. When the file finds 2 occurences it outputs 2 however in the next line when there are no occurences it outputs 1. here is the code: Code: #include <iostream.h>
#include <fstream.h>
#include <cstring>
const int MAXSTRING = 45; // constant to define maximum input string length throughout the program
typedef char characterString[MAXSTRING]; //allowing space for null byte
int compairText(characterString target, characterString input, int lineNumber, int numberOfCharacters);
void convertText(characterString input);
int main()
{
characterString input; //input string
characterString target; //target string
int numberOfCharacters = 0; //number of characters in the target string
int lineNumber = 1; //number of lines
int numberOfMatches = 0; //keeps the number of matches found
ifstream infile; //input file
ofstream outfile; //output file
infile.open("hw02.dat");
outfile.open("Output.dat");
cout << "Enter the word to search for: " << endl;
cin >> target;
convertText(target);
numberOfCharacters = strlen(target);
cout << numberOfCharacters << endl;
cout << "Line Number \t Number of Matches" << endl;
while(infile.peek() != EOF)
{
infile.getline(input, MAXSTRING, '\n');
convertText(input);
numberOfMatches = compairText(target, input, numberOfMatches, numberOfCharacters);
cout << lineNumber << "\t\t\t" << numberOfMatches << endl;
outfile << lineNumber << "\t\t\t" << numberOfMatches << endl;
lineNumber++;
numberOfMatches = 0;
}
infile.close();
outfile.close();
return 0;
}
//****************************************************
void convertText(characterString x)
{
for(int i = 0; i < MAXSTRING; i++)
if(x[i] >= 65 && x[i] <= 90)
x[i] += 32;
}
//****************************************************
int compairText(characterString target, characterString input, int numberOfMatches, int numberOfCharacters)
{
int targetPosition = 0;
for(int inputPosition = 0; inputPosition < MAXSTRING; inputPosition++)
{
if(input[inputPosition] == target[targetPosition])
{
targetPosition++;
if(targetPosition == numberOfCharacters)
{
targetPosition = 0;
numberOfMatches++;
}
}
else
{
targetPosition = 0;
if(input[inputPosition] == target[targetPosition])
targetPosition++;
}
}
return numberOfMatches;
}
-Bill |
| Maverik is offline |
| | #12 |
| Registered User Join Date: Apr 2003
Posts: 33
| ohh and here is the file i used to search, the word i was looking for is "release". reaadfna release adgadgrereleaseadgadg adfad adgadg release adfad release afdadf adfadf adfadf release |
| Maverik is offline |
| | #13 |
| Registered User Join Date: Apr 2003
Posts: 33
| ok i think i got it but i still don't understand why it wouldn't work. What I changed is in bold here is the compair text function: Code: int compairText(characterString target, characterString input, int numberOfMatches, int numberOfCharacters)
{
int targetPosition = 0;
int length = strlen(input);
for(int inputPosition = 0; inputPosition < length; inputPosition++)
{
if(input[inputPosition] == target[targetPosition])
{
targetPosition++;
if(targetPosition == numberOfCharacters)
{
targetPosition = 0;
numberOfMatches++;
}
}
else
{
targetPosition = 0;
if(input[inputPosition] == target[targetPosition])
targetPosition++;
}
}
return numberOfMatches;
}
-Bill |
| Maverik is offline |
| | #14 |
| Registered User Join Date: Feb 2003
Posts: 490
| Here's the correction I made: following is the error: traversing the MAXIMUM LENGTH OF THE CHAR ARRAY beyond the end of the latest string Code: for(int k = 0; k < MAXSTRING-numberOfCharacters+1; k++) //traverses the input string plus
// everything left over from the PREVIOUS input string
actually I reduced the upper limit of the search still further - no point checking the last few letters if there are fewer than numberOfCharacters remaining in the string Code: for(int k = 0; k < (int)strlen(input)-numberOfCharacters+1; k++) //traverses only the new input string |
| R.Stiltskin is offline |
| | #15 |
| Registered User Join Date: Feb 2003
Posts: 490
| It's really annoying when people start multiple threads about a single issue. Answers are at your thread on the linux board: Unix/C++ problem |
| R.Stiltskin is offline |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Need help understanding a problem | dnguyen1022 | C++ Programming | 2 | 04-29-2009 04:21 PM |
| Memory problem with Borland C 3.1 | AZ1699 | C Programming | 16 | 11-16-2007 11:22 AM |
| Someone having same problem with Code Block? | ofayto | C++ Programming | 1 | 07-12-2007 08:38 AM |
| A question related to strcmp | meili100 | C++ Programming | 6 | 07-07-2007 02:51 PM |
| WS_POPUP, continuation of old problem | blurrymadness | Windows Programming | 1 | 04-20-2007 06:54 PM |