I have a c++ project split up in two different files and headers, but I'm having a problem with one specific .cpp and .h file. In the .cpp file, there's global variables declared in it, but I have to change them to where they are global. I tried placing them inside the functions in the .cpp file it is with, but it changed the functionality of the program.
The program is supposed to sensor and show @'s over "sensitive" words and it does that just fine once these variables stay global. When I move them into the functions in the .cpp file, the program runs alright, but it doesn't censor anything and outputs an uncensored version of the message. Why is it doing that and what can I do about this to keep it's functionality without having these variables declared globally?
here's the header:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#ifndef SENSITIVEWORDS_H
#define SENSITIVEWORDS_H
#include <string>
/// HEADER FILE FOR "sensitiveWords.h"
/// To use this and it's implementation, must write #include "sensitiveWords.h" in other files.
usingnamespace std;
/*
* Functions & data for maintaining and checking a list of
* sensitive words.
*
*/
bool isSensitive(std::string& wordFromMessage);
void addSensitiveWord (std::string& wordFromMessage);
#endif
#include "sensitiveWords.h"
#include "message.h" /// making use of the message header
file to allow the declared and implemented (message.cpp) functions to work in sensitiveWords.cpp
#include <iostream>
#include <string>
#include <fstream>
int numSensitiveWords = 0;
constint MaxSensitiveWords = 5000;
std::string sensitiveWords[MaxSensitiveWords];
/*
* Replace all characters of a sentence containing the index pos with '@'
* except for '/n'.
*/
/// Implement
void censorSentenceAt (string& msg, int pos)
{
int startcensor;
startcensor = findSentenceStart(msg, pos);
int stopcensor;
stopcensor = findSentenceStop(msg, pos);
for (int index = startcensor; index < stopcensor; ++index)
{
if (msg[index] != '\n')
{ msg[index] = '@'; }
}
}
/*checks to see if a word is in the list of
*sensitive words
*/
bool isSensitive(std::string& wordFromMessage)
{
string word = toLowerCase(wordFromMessage);
for (int i = 0; i < numSensitiveWords; ++i)
if (word == sensitiveWords[i])
returntrue;
returnfalse;
}
/* */
Either pass the values as local arguments or create a class to encapsulate it all.
Pass as arguments
1 2 3 4 5 6 7 8 9 10
bool isSensitive(
const std::string& wordFromMessage,
int numSensitiveWords,
std::string sensitiveWords[] )
{
std::string word = toLowerCase(wordFromMessage);
for (int i = 0; i < numSensitiveWords; ++i)
if (word == sensitiveWords[i])
returntrue;
returnfalse;
Encapsulate as class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
struct SensitiveWordCensor
{
constint MaxSensitiveWords = 5000;
std::string sensitiveWords[MaxSensitiveWords];
int numSensitiveWords;
...
bool isSensitive(const std::string& wordFromMessage)
{
string word = toLowerCase(wordFromMessage);
for (int i = 0; i < numSensitiveWords; ++i)
if (word == sensitiveWords[i])
returntrue;
returnfalse;
}
};
I think the class one would be more convenient for me. Thank you. I do have some questions. I realized that the code I wrote down above is missing a few things. So here's the updated one
struct CensoringSensitive {
constint MaxSensitiveWords = 5000;
int numSensitiveWords;
std::string sensitiveWords[MaxSensitiveWords];
};
bool isSensitive(std::string& wordFromMessage)
{
string word = toLowerCase(wordFromMessage);
for (int i = 0; i < numSensitiveWords; ++i)
if (word == sensitiveWords[i])
returntrue;
returnfalse;
}
/*
*adds a word to the list of sensitive words, if it is not already
*in the list of Sensitive words
*/
void addSensitiveWord (std::string& wordFromMessage)
{
string word = toLowerCase(wordFromMessage);
if (!isSensitive(word))
{
sensitiveWords[numSensitiveWords] = word;
++numSensitiveWords;
}
}
so when i encapsulate in a class, does this change anything in the header file? and should it look like this:
Three dots are a fairly universal abbreviation for "and so on".
The header file (.hpp) should describe your class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#ifndef TEEPER_CENSOR_HPP
#define TEEPER_CENSOR_HPP
#include <string>
struct CensoringSensitive {
// Values used by your class
constint MaxSensitiveWords = 5000;
int numSensitiveWords;
std::string sensitiveWords[MaxSensitiveWords];
// Methods AKA "member functions"
bool isSensitive(std::string& wordFromMessage);
void addSensitiveWord (std::string& wordFromMessage);
};
#endif
The .cpp file is where the methods are defined.
1 2 3 4 5 6 7 8 9
#include "censor.hpp"
#include <anything else you need that is not necessary to include in the header>
bool CensoringSensitive::isSensitive(std::string& wordFromMessage) {
...
}
...
@Duthomhas thank you :) I also have another .cpp file called censor.cpp and it has all of my remaining errors. It's telling me that I can't call a member function without object. What does it mean and how do I fix it?
here is my header:
1 2 3 4 5 6 7 8 9
struct Censoring{
int numSensitiveWords;
int MaxSensitiveWords;
std::string sensitiveWords[];
bool isSensitive(std::string& wordFromMessage);
void addSensitiveWord (std::string& wordFromMessage);
};
bool Censoring::isSensitive(std::string& wordFromMessage)
{
string word = toLowerCase(wordFromMessage);
for (int i = 0; i < numSensitiveWords; ++i)
if (word == sensitiveWords[i])
returntrue;
returnfalse;
}
/*
*adds a word to the list of sensitive words, if it is not already
*in the list of Sensitive words
*/
void Censoring::addSensitiveWord(std::string& wordFromMessage)
{
string word = toLowerCase(wordFromMessage);
if (!isSensitive(word))
{
sensitiveWords[numSensitiveWords] = word;
++numSensitiveWords;
}
}
void censorMessage (string& msg)
{
for (int i = 0; i < msg.length(); ++i)
{
if (wordBeginsAt(msg, i))
{
string word = extractWord(msg, i);
if (Censoring::isSensitive(word))
censorSentenceAt (msg, i);
}
}
}
/*
*reads sensitive words from file stream in
*/
void readSensitiveWords (istream& in)
{
string word;
while ((in >> word) && (word != "==="))
Censoring::addSensitiveWord(word);
getline (in, word);
}
/*
*reads message from file stream in
*/
string readMessage (istream& in)
{
string msg;
string line;
getline (in, line);
while (in)
{
msg = msg + line + "\n";
getline (in, line);
}
return msg;
}
int main()
{
/* ifstream input_text reads the 'input.txt' file which
contains the original text file that should be censored. */
ifstream input_text("input.txt");
if(!input_text)
{
cout<<"Sorry! 'input.txt' is an invalid file."<<endl; ///Show this error
if input.txt fails to open
}
/// if input_text opens fine, then do the ff:
readSensitiveWords(input_text);
string msg = readMessage(input_text);
censorMessage (msg);
/* ofstream output_text creates an output file called
"output.txt" that writes all the changes with the censored text.
When program is run, output.txt will display,
with @'s necessary in the words to be censored */
ofstream output_text;
output_text.open("output.txt");
output_text<<msg;
output_text.close();
cout << msg << flush;
return 0;
}
I'm getting the errors in line 10 and line 27 in my censor.cpp file
C:\prog\censor> dir
bad-words.txt
censor.cpp
censor.exe
input.txt
C:\prog\censor> censor bad-words.txt < input.txt > output.txt
C:\prog\censor> type output.txt
John: My old man took me *censored* fishing yesterday.
Jane: Man, you *censored* hate *censored* fishing!
John: Don't I *censored* know it!
C:\prog\censor>
Remember, a class is a type of thing, with methods that operate on data of that type. In order to use the methods, you must have a variable of that type to operate on.