what i'm writing is simple, well, it should be, but i'm getting this error and i don't know what else to do, my code look like this
int main()
{
char *option;
while(strcmp(option,"exit")!=0){
int opt = GetSystemDefaultUILanguage();
std::string lang;
switch(opt)
{
case 3082:
lang = "number 3082";
break;
case 1033:
lang = "number 1033";
break;
}
std::cout<<lang<<'\n';
std::cin>>option;
}
}
when i compile it there isn't errors, but when i run it, i get a this error
Project xxxx raised exception class EAccessViolation with message 'Access violation at address zzzzz'.Process stopped. Use Step or Run to continue.
EDITED:
This is my full code, now is more simple, but still the same result.
even if i try with an if/else statement it wont work, need some help here, thanks
Your program will always get an access violation because of the following lines:
char *option;
while(strcmp(option,"exit")!=0){
std::cin>>option;
You never initialize the pointer option, but then try to use it. Change your code to this:
int main()
{
std::string option;
while(option != "exit")
{
int opt = GetSystemDefaultUILanguage();
std::string lang;
switch(opt)
{
case 3082:
lang = "number 3082";
break;
case 1033:
lang = "number 1033";
break;
}
std::cout<<lang<<std::endl;
std::cin>>option;
}
}
I can't tell you the cause of the specific run-time error you're seeing, but I call tell you what's wrong with your program: hardcoded paths to user directories. Localized names are just one of a myriad of things that can go wrong with trying to guess the paths yourself.
DON'T DO THAT. Instead, read environment variables or call Shell APIs to find out where this particular user wants temporary data stored (or documents, pictures, desktop icons, etc).
Have a look at getenv("TEMP") and ShGetSpecialFolderPath
Your problem is this line:
std::cin>>option;
The variable option is declared as an uninitialized pointer to a character. Thus in the above statement, you are reading data into an unknown location.
Why do you use C style strings (char *) and C++ std::string?
You should get rid of C style strings (unless they are constant).
Try this:
#include <iostream>
#include <string>
int main(void)
{
std::string option;
do
{
std::cout << "Type exit to end program." << std::endl; // endl will flush output buffer
std::getline(cin, option); // Input a text line into "option".
} while (option != "exit"); // C-style string, used as a constant.
return 0;
}
You wrote
BlockquoteProject xxxx raised exception class EAccessViolation with message 'Access violation at address zzzzz'.Process stopped. Use Step or Run to continue.
So why don't you pause your program before crash, go to the location and put a breakpoint? If you still can't cope with that than upload your code to a filesharing server and give us the link ;)
Related
so probably a silly question but i'm not very familiar with C++ so...
Then i run this code, it crash with no error code after hitting the second if in the main
#include <fstream>
#include <string>
#include "day.cpp"
#include "appointement.cpp"
using namespace std;
// Flags are placed as constants to easy access
const string mod="mod", lst="lst", rmv="rmv";
const string add="add", title="-t", date="-d";
bool ispresent (string command, string flag)
{
int pos=command.find(flag);
if (pos==-1)
{
return false;
}
else
{
return true;
}
}
int main()
{
string command;
cout << "Hi, send command:";
//this is analysed and searched for flags
cin >> command;
//if the "add" is present, create a new event (userEvent)
if (ispresent (command, add))
{
cout << "add triggered";
ofstream saveFile;
saveFile.open("/tmp/.calendar/saveFile.txt");
appointement userEvent;
// this test always fail
if (ispresent(command, title))
{
//search for "-t" to add the title to the event
cout << "-t triggered";
int flag=command.find("-t")+2;
cout << "placed after -t";
userEvent.setTitle(command.substr(flag,command.find(" ")));
cout << "title set";
// search for "-d" to add the date to the event
if (command.substr(flag,flag)==date)
{
int flag=flag+2;
userEvent.setTimeNotification(command.substr(flag+2, command.find (" ")));
}
}
}
return 0;
}
at first i thought at a bad test, but running it into gdb given me this error :
ispresent (command=<error reading variable: Cannot access memory at address 0x6a9b6f7a416ff400>,
flag=<error reading variable: Cannot access memory at address 0x3>) at main.cpp:13
I understand that there is something going with access right to the variables but i don't understand what is actually going on...
I check for similar questions here, but nobody seems to explain that is actually going on and how to fix/avoid it in the future
So after #molbdnilo pointed out, my "command" isn't actually the way it thought it was and only contain the first string in the command (each white space breaks my command in multiples strings).
So the issue is then i call the second test, it cannot work because my "command" variable is smaller than the position i tried to test, so then the program call the memory space where the continuation of the variable should be i get an memory error since this program is not allowed to use this memory space.
I am using std::stol() to convert string to long type. However, if the user enters letters how do I ensure the exception gets caught?
The code can be found here.
Note: I have already got the right way for that question, I just need to know what to do instead of:
if ( !(stol(input)) ) // Yes, I know it's stupid to think the output would be bool
throw 'R';
std::stol() throws exceptions on input errors. Use a try..catch to catch them.
From a comment to another answer, there seems to be some ambiguity about the goal here. To answer the question in the title, to catch an exception you write a try ... catch block:
long get_value() {
for (;;) {
std::cout << "Enter a number: ";
std::string text;
std::cin >> text;
try {
return stol(text);
} catch(...) {
std::cout << "Invalid input\n";
}
}
}
But the comment suggests that the solution of scanning the entire input text to see if there's a letter anywhere is appropriate. If the goal is to require that the input consist only of digits, you don't need to scan every character before calling std::stol. It's smarter than you think.
int last;
std::stol(text, &last);
if (last != text.length())
// got a bad character
This detects input like "123q".
As always, read the documentation.
For the sake of me better understanding C++ strings, array and pointers; I want to know: Why is it that I can use a condition whereby I check if the index has reached the null-terminating character like this...
const char* myString = "Grandopolous";
for (int i = 0;;i++)
{
if (!myString[i])
break;
else
cout << myString[i];
}
So that works just fine. Here I am instead checking to see if the character equals something other than the null-terminating character and so I expect that if it doesn't the result should be not 0 and the condition should be true. but this does not work, and I simply cannot fathom why:
const char* myString = "Grandopolous";
for (int i = 0;;i++)
{
if (myString[i])
cout << myString[i];
}
This does not work on my machine and crashes, also it outputs a lot of unreadable error messages mixed with strange symbols. I don't think that part matters although it is the first time error have been printed to my console application instead of the debug console.
The reason I mentioned pointers is because I managed to get the condition to work using pointers instead of the array index syntax which I find much easier to read.
So could someone please help me understand why my first bit of code is valid and why my second is not.
It does work. The check for null isn't the problem.
Your program crashes because you got rid of the break so your program overruns the array then continues forever into the abyss.
Your debugger would surely have revealed this to you as you stepped through the program, observing i.
To reverse the logic of your first example, write:
const char* myString = "Grandopolous";
for (int i = 0;;i++)
{
if (myString[i])
cout << myString[i];
else
break;
}
Suppose we have a menu which presents the user with some options:
Welcome:
1) Do something
2) Do something else
3) Do something cool
4) Quit
The user can press 1 - 4 and then the enter key. The program performs this operation and then presents the menu back to the user. An invalid option should just display the menu again.
I have the following main() method:
int main()
{
while (true)
switch (menu())
{
case 1:
doSomething();
break;
case 2:
doSomethingElse();
break;
case 3:
doSomethingCool();
break;
case 4:
return 0;
default:
continue;
}
}
and the follwing menu():
int menu()
{
cout << "Welcome:" << endl
<< "1: Do something" << endl
<< "2: Do something else" << endl
<< "3: Do something cool" << endl
<< "4: Quit" << endl;
int result = 0;
scanf("%d", &result);
return result;
}
Entering numerical types works great. Entering 1 - 4 causes the program to perform the desired action, and afterwards the menu is displayed again. Entering a number outside this range such as -1 or 12 will display the menu again as expected.
However, entering something like 'q' will simply cause the menu to display over and over again infinitely, without even stopping to get the user input.
I don't understand how this could possibly be happening. Clearly, menu() is being called as the menu is displayed over and over again, however scanf() is part of menu(), so I don't understand how the program gets into this error state where the user is not prompted for their input.
I originally had cin >> result which did exactly the same thing.
Edit: There appears to be a related question, however the original source code has disappeared from pastebin and one of the answers links to an article which apparently once explained why this is happening, but is now a dead link. Maybe someone can reply with why this is happening rather than linking? :)
Edit: Using this example, here is how I solved the problem:
int getNumericalInput()
{
string input = "";
int result;
while (true)
{
getline(cin, input);
stringstream sStr(input);
if (sStr >> result)
return result;
cout << "Invalid Input. Try again: ";
}
}
and I simply replaced
int result = 0;
scanf("%d", &result);
with
int result = getNumericalInput();
When you try to convert the non-numeric input to a number, it fails and (the important part) leaves that data in the input buffer, so the next time you try to read an int, it's still there waiting, and fails again -- and again, and again, forever.
There are two basic ways to avoid this. The one I prefer is to read a string of data, then convert from that to a number and take the appropriate action. Typically you'll use std::getline to read all the data up to the new-line, and then attempt to convert it. Since it will read whatever data is waiting, you'll never get junk "stuck" in the input.
The alternative is (especially if a conversion fails) to use std::ignore to read data from the input up to (typically) the next new-line.
1) Say this to yourself 1000 times, or until you fall asleep:
I will never ever ever use I/O functions without checking the return value.
2) Repeat the above 50 times.
3) Re-read your code: Are you checking the result of scanf? What happens when scanf cannot convert the input into the desired format? How would you go about learning such information if you didn't know it? (Four letters come to mind.)
I would also question why you'd use scanf rather than the more appropriate iostreams operation, but that would suffer from exactly the same problem.
You need to verify if the read succeeded. Hint: it did not. Always test after reading that you successfully read the input:
if (std::cin >> result) { ... }
if (scanf("%d", result) == 1) { ... }
In C++ the failed state is sticky and stays around until it gets clear()ed. As long as the stream is in failed state it won't do anything useful. In either case, you want to ignore() the bad character or fgetc() it. Note, that failure may be due to having reached the end of the stream in which case eof() is set or EOF is returned for iostream or stdio, respectively.
I am using getopt_long to process command line arguments in a C++ application. The examples all show something like printf("Username: %s\n", optarg) in the processing examples. This is great for showing an example, but I want to be able to actually store the values for use later. Much of the rest of the code uses string objects instead of char* so I need to cast/copy/whatever the contents of optarg into a string.
string bar;
while(1) {
c = getopt_long (argc, argv, "s:U:", long_options, &option_index);
if (c == -1) break;
switch(c)
{
case 'U':
// What do I need to do here to get
// the value of optarg into the string
// object bar?
bar.assign(optarg);
break;
}
}
The above code compiles, but when it executes I get an Illegal instruction error if I try to print out the value of bar using printf (it seems to work just fine for cout).
// Runs just fine, although I'm not certain it is actually safe!
cout << " bar: " << bar << "\n";
// 'Illegal instruction'
printf(" bar: %s\n", bar);
I do not know enough about command line debugging to better dig into what the illegal instruction might be. I had been running valgrind, but the sheer volume of memory errors that result from this error have made it difficult for me to pinpoint exactly what might be causing this error.
You told printf that you were suppling a c style string (null terminated array of chars) when specifying %s, but you provided a string class instead. Assuming you are using std::string try:
printf("bar : %s\n", bar.c_str());
printf() can't handle C++ strings. Use bar.c_str() instead.
cout << " bar: " << bar << "\n";
is perfectly safe. What makes you think it might not be?