C++ basic syntax errors - c++

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.

Related

i have an assignment that works in compiler but does not work properly in assignment website

I have a homework that requires me to do operations on a string, I used an iterator in the second function to find the last index of a letter in the string and first index of it to find the distance between them.
here is my code, focus on int textProcessing(const string &inputString, char letter); function:
#include <iostream>
#include <fstream>
#include <string>
#include<algorithm>
#include <iomanip>
#include <iterator>
using namespace std;
void textProcessing(string &inputString);
int textProcessing(const string &inputString, char letter);
void textProcessing(string &inputString, char orgChar, char newChar);
int main() {
ofstream out("text.txt");
out<<"the earth is a very small stage in a vast cosmic arena";
out.close();
unsigned short operation;
cin >> operation;
string sentence;
fstream inputstream;
inputstream.open("text.txt");
while (!inputstream.eof()) {
getline(inputstream, sentence);
if (sentence.length() > 0) {
// Your code starts here
if (operation==0){
textProcessing(sentence);
}
else if(operation==1){
char rletter;
cin>>rletter;
if(isupper(rletter)){
cout<<"Invalid";
}
else {
int ans = textProcessing(sentence, rletter);
cout << ans;
}
}
else if(operation==2){
char orignal;
char newl;
cin>>orignal>>newl;
textProcessing(sentence,orignal,newl);
}
else{
cout<<"Invalid";
}
// Your code ends here
}
}
return 0;
}
void textProcessing(string &inputString){
inputString.erase(remove(inputString.begin(),inputString.end(),'a'),inputString.end());
inputString.erase(remove(inputString.begin(),inputString.end(),'o'),inputString.end());
inputString.erase(remove(inputString.begin(),inputString.end(),'u'),inputString.end());
inputString.erase(remove(inputString.begin(),inputString.end(),'w'),inputString.end());
inputString.erase(remove(inputString.begin(),inputString.end(),'y'),inputString.end());
inputString.erase(remove(inputString.begin(),inputString.end(),'i'),inputString.end());
inputString.erase(remove(inputString.begin(),inputString.end(),'e'),inputString.end());
cout<<inputString;
};
int textProcessing(const string &inputString, char letter){
int count=0;
auto it=find(inputString.rbegin(),inputString.rend(),letter);
int last_index =distance(inputString.begin(), (it + 1).base());
int first=inputString.find(letter);
int distance=(last_index-first);
return distance;
};
void textProcessing(string &inputString, char orgChar, char newChar){
if((isupper(orgChar))/*||(isupper(newChar))*/){
cout<<"Invalid";
}
else {
for (int i = 0; i <= inputString.length(); i++) {
if (inputString[i] == orgChar) {
inputString[i] = newChar;
}
}
cout<<inputString;
}
}
and here is the error from assignment website:
Your program displayed : student.cpp: In function ‘int textProcessing(const string&, char)’: student.cpp:79:10: error: ‘it’ does not name a type
System Message: ERROR/3 (<string>, line 3)
Unexpected indentation.
auto it=find(inputString.rbegin(),inputString.rend(),letter);
^
System Message: WARNING/2 (<string>, line 5)
Block quote ends without a blank line; unexpected unindent.
student.cpp:80:52: error: ‘it’ was not declared in this scope
int last_index =distance(inputString.begin(), (it + 1).base());
^
The problem ‘it’ does not name a type is most surely caused by the use of auto in a Pre-C++11 standard compiler.
Make sure you're using C++11 or higher as auto is a C++11 feature.
There may be other problems with your code but the question is about the compiler error ‘it’ does not name a type.
There are many other online websites to compile and run your program one of which is this.

toupper tolower not working , help what's wrong with my code

main.cpp
#include <iostream>
#include "Module2.h"
int main()
{
std::cout<<"This is a test of Module2.h"<<std::endl;
std::cout<<UCase("This is a test of UCase")<<std::endl;
std::cout<<LCase("This is a test of LCase")<<std::endl;
system("pause");
return 0;
}
Module2.h
#include <iostream>
#include "Module2.h"
int main()
{
std::cout<<"This is a test of Module2.h"<<std::endl;
std::cout<<UCase("This is a test of UCase")<<std::endl;
std::cout<<LCase("This is a test of LCase")<<std::endl;
system("pause");
return 0;
}
Module2.cpp
///////////////////////////////////////////////////
//Module : Module2.cpp
//
//Purpose : Shows the usage of modular functions
///////////////////////////////////////////////////
#include "Module2.h"
///////////////////////////////////////////////////
//UCase()
char *UCase(char *str)
{
//convert each char in the string to uppercase
//
int len = strlen(str);
for ( int i ; i < len ; i++)
{
std::cout<<"In UCase"<<std::endl;
str[i]=toupper(str[i]);
}
return str;
}
///////////////////////////////////////////////////
//LCase()
char *LCase(char *str)
{
//convert each char in the string to uppercase
//
int len = strlen(str);
for ( int i ; i < len ; i++)
{
std::cout<<"In LCase"<<std::endl;
str[i]=tolower(str[i]);
}
return str;
}
When I run it there is no warning or error .
But , it don't upper and lower the string .
I have thought my for loops are wrong , but it seems to be right .
What's wrong with my code.
The main problem is that you are trying to modify string literals such as "This is a test of UCase". This is undefined behaviour. You need to copy the literals into a char array that you can modify.
Also note that binding char* to a string literal is deprecated and forbidden, for good reason. This should have emitted a warning:
UCase("This is a test of UCase") // not good: binding char* to literal
There are other problems with your code: undefined behaviour (UB) in loops with uninitialized variables,
for ( int i ; i < len ; i++) // using uninitialized i: UB
You should also have a look at toupper and tolower documentation. They both accept int with some restrictions on their values. You have to ensure you don't pass a value that causes undefined behaviour, bearing in mind that char can be signed. See for example Do I need to cast to unsigned char before calling toupper?
Loops like this one have undefined behavior:
for ( int i ; i < len ; i++)
The reason is that you did not start i at value 0.
You have no idea what value i starts at!
It could be -10, could be 824.
If you want a value to be initialized, you have to initialize it.
I suggest:
for (int i=0; i < len; i++)
char *UCase( char *str)
{
char ch;
int i=0;
while(str[i])
{
ch=str[i];
putchar(toupper(ch));
//putchar : The value is internally converted to an unsigned char when written.
i++;
}
}
///////////////////////////////////////////////////
//LCase()
char *LCase(char *str)
{
char ch;
int i=0;
while(str[i])
{
ch=str[i];
putchar(tolower(ch));
i++;
}
}
I finally write this .
Although , I still not quite understand , but I learned
#include <ctype.h>
int tolower( int ch );
means tolower toupper can change only one character each time , so I can not
tolower ("This is a test of LCase");
code like this .

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".

Translation/Transliteration problems

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
}}

passing vector<char> to a pointer char*

how do I pass a char vector to a char*? I know this problem could easily be solved with a predefined char[] array with a SIZE const, but I want the flexibility of a vector because there will be no predefined size.
using namespace std;
//prototype
void getnumberofwords(char*);
int main() {
//declare the input vector
vector<char> input;
/*here I collect the input from user into the vector, but I am omitting the code here for sake of brevity...*/
getnumberofwords(input);
//here is where an ERROR shows up: there is no suitable conversion from std::vector to char*
return 0;
}
void getnumberofwords(char *str){
int numwords=0;
int lengthofstring = (int)str.size();
//this ERROR says the expression must have a case
//step through characters until null
for (int index=0; index < lengthofstring; index++){
if ( *(str+index) == '\0') {
numwords++;
}
}
}
You can use data() member to get the pointer to the underlying array:
getnumberofwords(input.data());
The most obvious is to pass &your_vector[0]. Be sure to add a NUL to the end of your vector first though.
Alternatively, use std::string instead of std::vector<char>, in which case you can get a NUL-terminated string with the c_str member function.
Edit: I have to wonder, however, why getnmberofwords would be written to accept a char * unless it's some old C code that you just can't get away from using.
Given a typical definition of "word" counting some words that start out in a string can be done something like this:
std::istringstream buffer(your_string);
size_t num_words = std::distance(std::istream_iterator<std::string>(buffer),
std::istream_iterator<std::string>());
You should pass the reference of the vector to the function getnumberofwords.
void getnumberofwords(vector<char>& str){
int numwords=0;
int lengthofstring = str.size();
for (int index=0; index < lengthofstring; index++){
if ( str[index] == '\0') {
numwords++;
}
}
}
There is no method for converting the type from vector to pointer.
here's what I ended up doing which worked:
#include <iostream>
#include <cstring>
#include <string>
#include <iomanip>
using namespace std;
//prototype
void getnumberofwords(char*);
void getavgnumofletters(char*, int);
int main() {
const int SIZE=50;
char str[SIZE];
cout<<"Enter a string:";
cin.getline(str, SIZE);
getnumberofwords(str);
return 0;
}
void getnumberofwords(char *str){
int numwords=0;
int lengthstring=strlen(str);
//step through characters until null
for (int index=0; index < lengthstring; index++){
if (str[index] ==' ') {
numwords++;
}else{
continue;
}
}
numwords+=1;
cout<<"There are "<<numwords<<" in that sentence "<<endl;
getavgnumofletters(str, numwords);
}
void getavgnumofletters(char *str, int numwords) {
int numofletters=0;
double avgnumofletters;
int lengthstring=strlen(str);
//step through characters until null
for (int index=0; index < lengthstring; index++){
if (str[index] != ' ') {
numofletters++;
}else{
continue;
}
}
avgnumofletters = (double)numofletters/numwords;
cout<<"The average number of letters per word is "<<setprecision(1)<<fixed<<avgnumofletters<<endl;
}
/*