"Illegal case" when using special symbols in case in c++ - c++

I have some problem, when I use special char case in c++. I try use '{' but it's over with error to.
Visual Studio 2010.
Here is my code.
for (int i = 0; i < inputString.length(); i++)
{
switch(inputString[i])
case '{':
nowChar = inputString[i];
nowCaret = i;
break;
case '[':
nowChar = inputString[i];
nowCaret = i;
break;
case '(':
nowChar = inputString[i];
nowCaret = i;
break;
}
How I can remove these errors? I really don't have any idea about it.

You need to open and end your switch with braces.
switch() {
// ...
}

You might have just forgot the brace for the switch statement. Btw, it will be better to have default in a switch statement.
for (int i = 0; i < inputString.length(); i++)
{
switch(inputString[i]) {
case '{':
nowChar = inputString[i];
nowCaret = i;
break;
case '[':
nowChar = inputString[i];
nowCaret = i;
break;
case '(':
nowChar = inputString[i];
nowCaret = i;
break;
default:
break;
}
}

You forgot to use { and } around the cases:
switch(inputString[i])
{ //<------------------------------ this
case '{':
nowChar = inputString[i];
nowCaret = i;
break;
case '[':
nowChar = inputString[i];
nowCaret = i;
break;
case '(':
nowChar = inputString[i];
nowCaret = i;
break;
} //<------------------------------- and this
A switch block starts with { when it has multiple cases. If it has just one case, then { and } are not mandatory.
switch(i)
case 0 :
// code
break;
Here { and } are not mandatory.

Related

c++ An interesting result [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
This code somehow always adds to the conclusion 12142.
For example insert 12; the output is 1212142, insert 1 + 2; get 312142
#include "stdafx.h"
#include <iostream>
using namespace std;
class Token
{
public:
char kind;
double value;
};
class Token_stream
{
public:
Token get();
void putback(Token t);
private:
bool full{ false };
Token buffer;
};
void Token_stream::putback(Token t)
{
buffer = t;
full = true;
}
Token Token_stream::get()
{
if (full)
{
full = false;
return buffer;
}
char ch;
cin >> ch;
switch (ch)
{
case ';':
case 'q':
case '(': case ')': case '+':
case '-': case '*': case '/':
return Token{ ch };
case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
cin.putback(ch);
double val;
cin >> val;
return Token{ '8',val };
}
default:
throw runtime_error("dont true token");
break;
}
}
Token_stream ts;
double expres();
double prim()
{
Token t = ts.get();
switch (t.kind)
{
case '(':
{
double d = expres();
t = ts.get();
if (t.kind != ')')
{
throw runtime_error("))))");
}
return d;
}
case '8':
return t.value;
default:
throw runtime_error("perm");
}
}
double term()
{
double left = prim();
Token t = ts.get();
while (true)
{
switch (t.kind)
{
case '*':
left *= prim();
t = ts.get();
break;
case '/':
{
double d = prim();
if (d == 0)
{
throw runtime_error("/0");
}
left /= d;
t = ts.get();
break;
}
default:
ts.putback(t);
return left;
}
}
}
double expres()
{
{
double left = term();
Token t = ts.get();
while (true)
{
switch (t.kind)
{
case '+':
left += term();
t = ts.get();
break;
case '-':
left -= term();
t = ts.get();
break;
default:
ts.putback(t);
return left;
}
}
}
}
int main()
{
double val = 0;
while (cin)
{
Token t = ts.get();
if (t.kind == 'q') break;
if (t.kind == ';')
cout << "=" << val << '/n';
else
ts.putback(t);
val = expres();
}
return 0;
}
This code is taken from the book Programming - Principles and Practice Using C ++
Look here:
if (t.kind == ';')
cout << "=" << val << '/n';
'/n' is the character / followed by the character n, squeezed into what's known as a "multi-character literal". These are actually ints with implementation-defined values; on your system, apparently that's the number 12142.
You meant the single character '\n'.
In future, locate and solve problems like this by constructing a minimal testcase. In doing so, you would eventually have ended up with a test program that simply said cout << '/n' and output 12142; at that point, if you still didn't spot the typo, you'd have a very simple thing to look up and/or ask about.

New to c/c++ an confused with pointers

I'm fairly new to c/c++ programming and currently I'm working on some basic programms to get in touch with the language. My newest programm is a simple hex_xor function, that follows the instruction of Cryptopals Challenge 2. But I'm already getting errors and I'm assuming I am doing something horribly wrong with the pointers I am using.
Here is a part of my programm:
const char* hex_char_to_bin(char c)
{
switch(toupper(c))
{
case '0': return "0000";
case '1': return "0001";
case '2': return "0010";
case '3': return "0011";
case '4': return "0100";
case '5': return "0101";
case '6': return "0110";
case '7': return "0111";
case '8': return "1000";
case '9': return "1001";
case 'A': return "1010";
case 'B': return "1011";
case 'C': return "1100";
case 'D': return "1101";
case 'E': return "1110";
case 'F': return "1111";
}
}
const char* hex_binary(const char* c){
std::string result = "";
for(int i = 0; i < strlen(c); i++){
result += hex_char_to_bin(c[i]);
}
return result.c_str();
}
int main(){
std::string s1 = "1c0111001f010100061a024b53535009181c";
std::string s2 = "686974207468652062756c6c277320657965";
const char* bin1 = hex_binary(s1.c_str());
const char* bin2 = hex_binary(s2.c_str());
std::cout << bin1 << "\n" << bin2 << std::endl;
return 0;
}
The output is the following:
011010000110100101110100001000000111010001101000011001010010000001100010011101010110110001101100001001110111001100100000011001010111100101100101
011010000110100101110100001000000111010001101000011001010010000001100010011101010110110001101100001001110111001100100000011001010111100101100101
In both variables (bin1/2) is the binary conversion of the second hex-string. My aim is (obviously) to have both binary-strings saved in different variables, so I can proceed with my xor-function. Can someone point out where I am failing to achieve my goal and why? Other hints are welcome aswell!
You can't use result of c_str() when main string object is no longer alive. So, you're referencing already freed resources and facing undefined behavior.
If I were you, I'd change hex_binary() to return std::string and just return result back without using c_str()

c++ The evaluation of expression. How to exit the while loop?

I use stack to evaluate an expression.
The most important function is below:
double Expression_Eval()
{
SeqStack<char,100> OPTR;
SeqStack<double,100> OPND;
OPTR.Push('#');
char ch;
ch=getchar();
while (ch!='#' || OPTR.GetTop()!='#')
{
if (!InOPTR(ch))
{
int n=ch-'0';
double num=(double)n;
OPND.Push(num);
ch=getchar();
}
else
{
char pre_op=OPTR.GetTop();
switch (Precede(pre_op, ch))
{
case '<': OPTR.Push(ch);
ch=getchar();
break;
case '=': OPTR.Pop();
ch=getchar();
break;
case '>': double b=OPND.Pop();
double a=OPND.Pop();
pre_op=OPTR.Pop();
OPND.Push(Operate(a, pre_op, b));
ch=getchar();
break;
}
}
}
return OPND.GetTop();
}
Then, when I input 8/(5-3)#, it will not print the result.
I think the loop termination condition ch!='#' || OPTR.GetTop()!='#' is wrong.
When I press Enter, getchar() get the last char is CR but not #.
But, I don't know how to revise it to make my program work.
The other part of my program is below:
#include<iostream>
using namespace std;
template<typename DataType,int StackSize>
class SeqStack
{
private:
DataType data[StackSize];
int top;
public:
SeqStack()
{ top=-1; }
~SeqStack() {}
void Push(DataType x)
{
if(top == StackSize-1)
throw "error";
data[++top]=x;
}
DataType Pop()
{
if(top == -1)
throw "error";
DataType x=data[top--];
return x;
}
DataType GetTop()
{
if(top != -1)
return data[top];
else
cout<<"error";
}
};
bool InOPTR(char ch)
{
if( (ch>='(' && ch<='+') || ch=='-' || ch=='/' )
{
return true;
}else{
return false;
}
}
char Precede(char op1, char op2)
{
char pri[7][7]={ {'>','>','<','<','<','>','>'}
, {'>','>','<','<','<','>','>'}
, {'>','>','>','>','<','>','>'}
, {'>','>','>','>','<','>','>'}
, {'<','<','<','<','<','=','#'}
, {'>','>','>','>','#','>','>'}
, {'<','<','<','<','<','#','='} };
int m,n;
switch(op1)
{
case '+': m=0;break;
case '-': m=1;break;
case '*': m=2;break;
case '/': m=3;break;
case '(': m=4;break;
case ')': m=5;break;
case '#': m=6;break;
}
switch(op2)
{
case '+': n=0;break;
case '-': n=1;break;
case '*': n=2;break;
case '/': n=3;break;
case '(': n=4;break;
case ')': n=5;break;
case '#': n=6;break;
}
return pri[m][n];
}
double Operate(double a, char op, double b)
{
double result;
switch(op)
{
case '+': result=a+b; break;
case '-': result=a-b; break;
case '*': result=a*b; break;
case '/': result=a/b; break;
}
return result;
}
int main()
{
double r=Expression_Eval();
cout<<r<<endl;
return 0;
}
Problem seem to be that '#' is considered a number, but it should be considered an operation:
Use:
bool InOPTR(char ch) {
if ((ch >= '(' && ch <= '+') || ch == '-' || ch == '/' || ch=='#'){
return true;
}
else {
return false;
}
}
Note that '#' is ASCII 64 which is not covered in the ranage '(' to '+' [40-43]
Hope this helps.
You need to consume carriage return or newline character after getchar(); which comes into play when you press enter button.
One trick is as below.
ch=getchar();
getchar(); //this getchar to consume CR.
since you have used ch = getchar() many times you have to use above solution at many places.
Better solution to this problem will be to enter string instead of entering single character using getchar()...
Hope you got what I am trying to say...

Occasional unhandled exception with atoi(string.c_str()) Updated

UPDATE
I thought stoi(string) solved it, but it only worked for a little while.
I have added the code for splitString and decrypt below.
I occasionally get unhandled exceptions with atoi() using the supposable same value.
My code looks like this:
ifstream myfile ("Save.sav");
string line = "";
if (myfile.is_open())
{
while ( myfile.good() )
{
getline (myfile,line);
}
myfile.close();
line = StaticFunctions::decrypt(line);
}
vector<string> splitString = StaticFunctions::splitString(line, 's');
return atoi(splitString[0].c_str());
So what it does is reading a savefile, then it decrypts it and then it splits the string by every 's'. When I'm debugging, the savefile is always the same and the first value is 3.
This work sometimes, maybe every 10 attempt. So every 9 out of 10 attempts I get unhandled exception at ... at memory location.
Monitoring the converted value shows it always returns 3 and then the application doesn't crash until I start the game which is a bit further in the code.
If I remove the atoi and just return 3 the application works fine.
I've tried strtod but it didn't help.
Thanks,
Markus
SplitString code:
vector<string> StaticFunctions::splitString(string str, char splitByThis)
{
vector<string> tempVector;
unsigned int pos = str.find(splitByThis);
unsigned int initialPos = 0;
// Decompose statement
while( pos != std::string::npos ) {
tempVector.push_back(str.substr( initialPos, pos - initialPos + 1 ) );
initialPos = pos + 1;
pos = str.find(splitByThis, initialPos );
}
// Add the last one
tempVector.push_back(str.substr(initialPos, std::min(pos, str.size()) - initialPos + 1));
return tempVector;
}
Decrypt code (very simple):
string StaticFunctions::decrypt(string decryptThis)
{
for(int x = 0; x < decryptThis.length(); x++)
{
switch(decryptThis[x])
{
case '*':
{
decryptThis[x] = '0';
break;
}
case '?':
{
decryptThis[x] = '1';
break;
}
case '!':
{
decryptThis[x] = '2';
break;
}
case '=':
{
decryptThis[x] = '3';
break;
}
case '#':
{
decryptThis[x] = '4';
break;
}
case '^':
{
decryptThis[x] = '5';
break;
}
case '%':
{
decryptThis[x] = '6';
break;
}
case '+':
{
decryptThis[x] = '7';
break;
}
case '-':
{
decryptThis[x] = '8';
break;
}
case '"':
{
decryptThis[x] = '9';
break;
}
}
}
return decryptThis;
}
Try use strtol instead
strtol (splitString[0].c_str(),NULL,10);
stoi(string) instead of atoi(string.c_str()) solved it.
UPDATE:
It did not solve it.

Returning a formatted string from a time structure

I wrote a little structure for getting certain time information. This structure is a helper,
for my logging class im planning to write. Here is the code:
struct UTime
{
char Month [4];
char DayOfMonth [3];
char DayOfWeek [4];
char Year [5];
char Time [9];
char Full [25];
UTime()
{
this->refresh();
}
void refresh()
{
char TimeBuffer[26] = {};
time_t RawTime = 0;
time(&RawTime);
ctime_s(TimeBuffer, 26*sizeof(char), &RawTime);
this->DayOfWeek[0] = TimeBuffer[0];
this->DayOfWeek[1] = TimeBuffer[1];
this->DayOfWeek[2] = TimeBuffer[2];
this->DayOfWeek[3] = 0;
this->Month[0] = TimeBuffer[4];
this->Month[1] = TimeBuffer[5];
this->Month[2] = TimeBuffer[6];
this->Month[3] = 0;
this->DayOfMonth[0] = TimeBuffer[8];
this->DayOfMonth[1] = TimeBuffer[9];
this->DayOfMonth[2] = 0;
this->Time[0] = TimeBuffer[11];
this->Time[1] = TimeBuffer[12];
this->Time[2] = TimeBuffer[13];
this->Time[3] = TimeBuffer[14];
this->Time[4] = TimeBuffer[15];
this->Time[5] = TimeBuffer[16];
this->Time[6] = TimeBuffer[17];
this->Time[7] = TimeBuffer[18];
this->Time[8] = 0;
this->Year[0] = TimeBuffer[20];
this->Year[1] = TimeBuffer[21];
this->Year[2] = TimeBuffer[22];
this->Year[3] = TimeBuffer[23];
this->Year[4] = 0;
memcpy(this->Full, TimeBuffer, 25);
this->Full[24] = 0;
}
}; // struct UTime;
Now Id like to add a function wich returns a formatted version of the time information.
For example:
std::string formatted = utime.get(Year, Month)
This function should return something like: "2011 Nov", or another example:
std::string formated = utime.get(DayOfWeek, Time);
This function should return something like: "Mon 20:43:24". Can anyone please point me in the most effecient way to do this? Im just not sure about effeciency because in a logger this function might get called alot. Thank you very much.
You can use strftime. It supports lots of format
std::string utime::get(char* format) {
std::string formatted;
formatted.reserve(30);
for( ; *format!='\0'; ++format) {
if (*format != '%')
formatted.append(*format);
else {
++format;
switch (*format) {
case 'a': formatted.append(DayOfWeek); break;
case 'b': formatted.append(Month); break;
case 'd': formatted.append(DayOfMonth); break;
case 'H': formatted.append(Time, 2); break;
case 'M': formatted.append(Time+3, 2); break;
case 'S': formatted.append(Time+6, 2); break;
case 'x': formatted.append(Month);
formatted.append(' ');
formatted.append(DayOfMonth);
formatted.append(' ');
formatted.append(Year);
break;
case 'X': formatted.append(Time); break;
case 'y': formatted.append(Year+2); break;
case 'Y': formatted.append(Year); break;
case '%': formatted.append('%'); break;
default: throw std::logic_error("Unsupported string format");
};
}
}
return formatted;
}
This should be fairly fast since it reserves a fair amount of space, and simply appends chacters to the end of the already allocated buffer most of the time. I highly recommend matching a standard formatting scheme like strftime as parapura rajkumar suggested.