Translation/Transliteration problems - c++

I am working on a translation/transliteration program, that reads an english story, and translates it to elvish, using an english/elvish dictionary. After the code shown below, i explain the error that i receive.
I have a lot of code, I am not sure if i should post it all, but I will post what I think should be sufficient. Apologies if my code seems bizarre - but I am only a beginner.
There is a main file, a header file with two Classes: Translator and Dictionary, and a cpp file to implement the class functions.
I have a constructor that reads in the dictionary file to dictFileName and copys the english words into englishWord, and the elvish words into elvishWord:
Translator::Translator(const char dictFileName[]) : dict(dictFileName)
{
char englishWord[2000][50];
char temp_eng_word[50];
char temp_elv_word[50];
char elvishWord[2000][50];
int num_entries;
fstream str;
str.open(dictFileName, ios::in);
int i;
while (!str.fail())
{
for (i=0; i< 2000; i++)
{
str>> temp_eng_word;
str>> temp_elv_word;
strcpy(englishWord[i],temp_eng_word);
strcpy(elvishWord[i],temp_elv_word);
}
num_entries = i;
}
str.close();
}
In the main file, the english lines are read into the toElvish function, and tokenized into an array of words, temp_eng_words.
Within this toElvish function, I am calling another function; translate, which reads in temp_eng_words and is supposed to return the elvish words:
char Translator::toElvish(char elvish_line[],const char english_line[])
{
int j=0;
char temp_eng_words[2000][50];
//char temp_elv_words[2000][50]; NOT SURE IF I NEED THIS
std::string str = english_line;
std::istringstream stm(str);
string word;
while( stm >> word) // read white-space delimited tokens one by one
{
int k=0;
strcpy (temp_eng_words[k],word.c_str());
k++;
}
for (int i=0; i<2000;i++) // ERROR: out_s was not declared in this scope
{
Dictionary::translate (out_s,temp_eng_words[i]); // ERROR RELATES TO THIS LINE
}
}
This is the translate function:
char Dictionary::translate (char out_s[], const char s[])
{
int i;
for (i=0;i < numEntries; i++)
{
if (strcmp(englishWord[i], s)==0)
break;
}
if (i<numEntries)
strcpy(out_s,elvishWord[i]);
}
My problem is that when I run the program, I get the error '*out_s was not declared in this scope*'.
If you have read all of this, thanks; any suggestions/clues would be much appreciated. :)

As you can see in your code below, you have used out_s in your function, but you have not declared it in your function.
You can use global variables or local variables in your function. I suggest you read this
char Translator::toElvish(char elvish_line[],const char english_line[]) {
int j=0;
char temp_eng_words[2000][50];
//char temp_elv_words[2000][50]; NOT SURE IF I NEED THIS
std::string str = english_line;
std::istringstream stm(str);
string word;
while( stm >> word) // read white-space delimited tokens one by one
{
int k=0;
strcpy (temp_eng_words[k],word.c_str());
k++;
}
for (int i=0; i<2000;i++) // ERROR: out_s was not declared in this scope
{
Dictionary::translate (out_s,temp_eng_words[i]); // ERROR RELATES TO THIS LINE
}}

Related

Deprecated getch() - switching to recommended by compiler _getch() still causes problems

I would really need your help on this one and I hope I'll get some clue about my compiler error.
The problematic piece of my code:
char user_ch;
do {
user_ch=_getch(); // i changed it from getch() to fix the previous error, didn't help it seems
switch (user_ch) {
case '1': response='1'; break;
case '3': response='3';
}
} while (response!='1'||response!='3');
Compiler error (what's peculiar it's 'build' error instead of 'debug' error):
error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'
Compiler refers to this piece of code in fstream file:
private:
_Myfb _Filebuffer; // the file buffer
};
As someone pointed out I'm posting my usage of fstream functions and objects.
My functions parsing settings.txt file
bool read_bool(ifstream file, int verse) {
string temp_var;
for (int i=0; i<verse; i++)
getline(file, temp_var);
if (temp_var=="true") return true;
else return false; }
int read_int(ifstream file, int verse) {
string temp_var;
for (int i=0; i<verse; i++)
getline(file, temp_var);
return stoi(temp_var); }
t_direction read_t_dir(ifstream file, int verse) {
char temp_var;
for (int i=0; i<verse; i++)
file.get(temp_var);
t_direction pre_return;
switch (temp_var) {
case '1': pre_return=to_mother; break;
case '2': pre_return=to_foreign; break;
case '3': pre_return=rndom;
}
return pre_return; }
string read_string(ifstream file, int verse) {
string temp_var;
for (int i=0; i<verse; i++)
getline(file, temp_var);
return temp_var; }
size_t lines_count(ifstream if_file) {
size_t a=0;
string temp_str;
while (getline(if_file, temp_str))
++a;
return a; }
bool add_mistake(ofstream file, string mistake, string to_trans, string target) {
file << "Original: " << to_trans << "\nShould be: " << target;
file << "\nYour response: " << mistake;
file << "\n---------------------\n";
return true; }
For error-security sake i've never opened or closed fstream object inside a function.
// stream from file and tokenize
// SYNTAX FOR FILE (each line): word,word>word,word,word
words_input.open(FILE_NAME);
string buffer_line, token;
for (size_t i; i<number_of_lines; i++) {
getline(words_input, buffer_line);
istringstream language_split(buffer_line);
vector<string> container(2);
while (getline(language_split, token, '>')) // split languages
container.push_back(token); // hard coded to ignore possible elements 3, 4, 5...
istringstream synonym_source_split(container.at(0));
while (getline(synonym_source_split, token, ',')) // first language synonyms
source_words[i].push_back(token);
istringstream synonym_target_split(container.at(1));
while (getline(synonym_target_split, token, ',')) // second language synonyms
target_words[i].push_back(token);
}
words_input.close();
Thanks for any help!
Your issue is in this part of the code:
string read_string(ifstream file, int verse) {
string temp_var;
for (int i=0; i<verse; i++)
getline(file, temp_var);
return temp_var;
}
size_t lines_count(ifstream if_file) {
size_t a=0;
string temp_str;
while (getline(if_file, temp_str))
++a;
return a;
}
Both of these functions take as input a parameter of type ifstream. Since you're not taking in the ifstream by reference, when you call this function, C++ will try to initialize if_file to a copy of the ifstream that you passed in as a parameter. This isn't allowed, since ifstreams can't be copied. Unfortunately, you tend to get garbage error messages like the one you showed above instead of something more useful in this case.
To fix this, change your code so that you take the parameters by reference:
string read_string(ifstream& file, int verse) {
string temp_var;
for (int i=0; i<verse; i++)
getline(file, temp_var);
return temp_var;
}
size_t lines_count(ifstream& if_file) {
size_t a=0;
string temp_str;
while (getline(if_file, temp_str))
++a;
return a;
}
That said, there are likely other errors in your code. I would strongly recommend commenting your code as you go and testing pieces incrementally, since as written the code is pretty tough to follow.

C++, reading chars into a vector<char> from a file, character by character

I am trying to read in the first 7 chars of a file named "board.txt" into a vector<'char> but I am having issues for some reason. I am not too familiar with C++ so any advice would be appreciated, here is the code I have so far
//rack
int charCount = 0;
char ch;
ifstream rackIn("board.txt");
while(rackIn.get(ch) && charCount < 7){
this->getMyRack().push_back(ch);
}
And here is the function getMyRack used in the code above:
vector<char> board::getMyRack(){
return this->myRack;
}
myRack is a char vector
I tried to test this in my main using this:
for (int i = 0; i < test->getMyRack().size(); ++i){
cout << test->getMyRack().at(i);
}
but it does not output anything, why are the chars i am reading in not being added into my char vectors?
Because you don't put char in your vector. Your function getMyRack() returns vector but not address of your vector. You can add method to your class board for adding char, for example:
void board::addChar(char c){
this->myRack.push_back(c);
}
And then call this function:
while(rackIn.get(ch) && charCount < 7){
this->addChar(ch);
}
Or change the return type of your function.
read line one or (how much lines required) from file to a string
create substring of 7 chars from beginning
std::ifstream file("board.txt");
std::string str;
// to read single line
std::getline(file, str);
// to read 7 chars
str= str.substr(0,7);
vector<char> char_buf;
for(size_t i =0; i <= str.size();i++)
{
char_buf.push_back(str[i])
}
// use the char_buf
easier or second way is use
#include<fstream> // for ifstream
#include <cstdlib> // for exit()
std::string file_name ="board.txt";
std::ifstream input_stream;
std::vector<char> char_buf;
input_stream.open(file_name);
if(input_stream.fail()) { exit(0);}
int char_no=0;
while(i<=7)
{
char c = input_stream.get();
char_buf.push_back(c);
i++;
}
// use char_buf
std::string str;
int char_count=0;
// Read the next line from File untill it reaches the 7.
while (std::getline(in, str)&& char_count!=7)
{
// Line contains string of length > 0 then save it in vector
if (str.size() > 0)
your_char_vector.push_back(str);
char_count++;
if(char_count==7)
break;
}

Truncating and removing characters from char array C++

I basically have a txt file that looks like this...
High Score: 50
Player Name: Sam
Number Of Kills: 5
Map
Time
I want to store everything before the : or whitespace after Map and Time into one array and everything after in another. For both Map and Time, there is nothing after and so I want to store the whitespace as null.
So far, I have managed to read and store all this information into a temp array. However, it is separating that I am having trouble with. This is my code:
istream operator >> (istream &is, Player &player)
{
char **temp;
char **tempNew;
char lineInfo[200]
temp = new char*[5];
tempNew = new char*[5];
for (int i=0; i<5; i++)
{
temp[i] = new char[200];
is.getline(lineInfo, sizeof(lineInfo));
int length = strlen(lineInfo);
for (int z=0; z < length; z++)
{
if(lineInfo[z] == '= ' ){ //HOW DO I CHECK IF THERE IS NOTHING AFTER THE LAST CHAR
lineInfo [length - (z+1)] = lineInfo [length];
cout << lineInfo << endl;
strncpy(temp[i], lineInfo, sizeof(lineInfo));
}
else{
tempNew[i] = new char[200];
strncpy(tempNew[i], lineInfo, sizeof(lineInfo));
}
}
}
If what you need is to find ':'
#include <cstring>
and just
auto occurance = strstr(string, substring);
Documentation here.
if occurance is not a null ptr, then see if occurance is at the end of the line from get line. If not, your value is everything after that :
Much easier with std::string.
// Read high score
int high_score;
my_text_file.ignore(10000, ':');
cin >> high_score;
// Read player name
std::string player_name;
my_text_file.ignore(10000, ':');
std::getline(my_text_file, player_name);
// Remove spaces at beginning of string
std::string::size_type end_position;
end_position = player_name.find_first_not_of(" \t");
if (end_position != std::string::npos)
{
player_name.erase(0, end_position - 1);
}
// Read kills
unsigned int number_of_kills = 0;
my_text_file.ignore(':');
cin >> number_of_kills;
// Read "Map" line
my_text_file.ignore(10000, '\n');
std::string map_line_text;
std::getline(my_text_file, map_line_text);
// Read "Text" line
std::string text_line;
std::getline(my_text_file, text_line);
If you insist on using C-style strings (arrays of char), you will have to use more complex and less safe functionality. Look up the following functions:
fscanf, strchr, strcpy, sscanf

C++ basic syntax errors

I am getting errors with the following code and don't know where I am going wrong.
#include <iostream>
#include <fstream>
#include <cstring>
#include "Translator.h"
using namespace std;
int main (void)
{
char Dictionary::translate (char out_s[], const char s[])
{
int i;
for (i=0;i < numEntries; i++)
{
if (strcmp(englishWord[i], s)==0)
break;
}
if (i<numEntries)
strcpy(out_s,elvishWord[i]);
}
char Translator::toElvish(char elvish_line[],const char english_line[])
{
int j=0;
char temp_eng_words[2000][50];
//char temp_elv_words[2000][50]; NOT SURE IF I NEED THIS
std::string str = english_line;
std::istringstream stm(str);
string word;
while( stm >> word) // read white-space delimited tokens one by one
{
int k=0;
strcpy (temp_eng_words[k],word.c_str());
k++;
}
for (int i=0; i<2000;i++) // ERROR: out_s was not declared in this scope
{
Dictionary::translate (out_s,temp_eng_words[i]); // ERROR RELATES TO THIS LINE
}
}
Translator::Translator(const char dictFileName[]) : dict(dictFileName)
{
char englishWord[2000][50];
char temp_eng_word[50];
char temp_elv_word[50];
char elvishWord[2000][50];
int num_entries;
fstream str;
str.open(dictFileName, ios::in);
int i;
while (!str.fail())
{
for (i=0; i< 2000; i++)
{
str>> temp_eng_word;
str>> temp_elv_word;
strcpy(englishWord[i],temp_eng_word);
strcpy(elvishWord[i],temp_elv_word);
}
num_entries = i;
}
str.close();
}
}}
The first error I get is around
char Dictionary::translate (char out_s[], const char s[])
{
int i;
where it says "A function definition is not allowed before a '{' token. The second error I get is at the that there is an expected '}' at the end of input, but no matter how many i put in or leave out it still gives the same error message.
And ideas??
You're defining all the functions inside main(). Move them all before main().
You shouldn't define a function right within another function.
Function definitions come after each other.
It's not allowed to declare inner functions in C++.
Move your functions to a distinct scope, without nesting into main.

Initializer but incomplete type?

The following code gives me 2 errors when i compile
#include <iostream>
#include <fstream>
#include <cstring>
#include "Translator.h"
using namespace std;
void Dictionary::translate(char out_s[], const char s[])
{
int i;
char englishWord[MAX_NUM_WORDS][MAX_WORD_LEN];
for (i=0;i < numEntries; i++)
{
if (strcmp(englishWord[i], s)==0)
break;
}
if (i<numEntries)
strcpy(out_s,elvishWord[i]);
}
char Translator::toElvish(const char elvish_line[],const char english_line[])
{
int j=0;
char temp_eng_words[2000][50];
//char temp_elv_words[2000][50]; NOT SURE IF I NEED THIS
std::string str = english_line;
std:: istringstream stm(str);
string word;
while( stm >> word) // read white-space delimited tokens one by one
{
int k=0;
strcpy (temp_eng_words[k],word.c_str());
k++;
}
for (int i=0; i<2000;i++) // ERROR: out_s was not declared in this scope
{
Dictionary::translate (out_s,temp_eng_words[i]); // ERROR RELATES TO THIS LINE
}
}
Translator::Translator(const char dictFileName[]) : dict(dictFileName)
{
char englishWord[2000][50];
char temp_eng_word[50];
char temp_elv_word[50];
char elvishWord[2000][50];
int num_entries;
fstream str;
str.open(dictFileName, ios::in);
int i;
while (!str.fail())
{
for (i=0; i< 2000; i++)
{
str>> temp_eng_word;
str>> temp_elv_word;
strcpy(englishWord[i],temp_eng_word);
strcpy(elvishWord[i],temp_elv_word);
}
num_entries = i;
}
str.close();
}
}
The first one is at std::string istringstream stm(str); where it says it the variable has an initializer but incomplete type. If I put in std::string istringstream stm(str); it says expected initializer before stm andstm was not declared in the scope.
It also says out_s was not declared in this scope at Dictionary::translate (out_s,temp_eng_words[i]);. I don't see why one parameter is recognisied and one is not?
Thanks in advance.
You have to include header file:
#include <sstream>
#include <string>
when you want to use stringstream and string.
Meanwhile:
Dictionary::translate (out_s,temp_eng_words[i]);
If out_s is not a member of the class, you seems forgot to define out_s before using it inside toElvish.
Meanwhile:
while( stm >> word) // read white-space delimited tokens one by one
{
int k=0; //^^Why do you initialize k everytime you read a word?
strcpy (temp_eng_words[k],word.c_str());
k++;
}
You just need to include sstream
Your translator would be much simpler if you used std::map.
#include <map>
#include <string>
// map[english word] returns the elvish word.
typedef std::map<std::string, std::string> Dictionary;
// Define the dictionary
Dictionary english_to_elvish_dictionary;
std::string To_Elvish(const std::string& english_word)
{
Dictionary::iterator iter;
std::string elvish_word;
iter = english_to_elvish_dictionary.find(english_word);
if (iter != english_to_elvish_dictionary.end())
{
// English word is in dictionary, return the elvish equivalent.
elvish_word = *iter;
}
return elvish_word;
}
The above code fragment replaces most of your code and reduces your issues with arrays of arrays of C-strings. Less code == less problems.
To see a list of issues your having, search StackOverflow for "[c++] elvish english".