Exception thrown: write access violation. _My_data was 0x7001AC - c++

I'm a C++ starter. I tried writing a code that gets a certain string, for instance - "there1hello0". I tried to make a sentence from it, following this rule:
Each word ends with a number that specifies it's place in the sentence.
Therefore the the sentence is: "hellothere".
My code:
void analyze()
{
string Given = "there1hello0";
int flag = 0;
string word = "";
string Display[2];
for (int i = 0; i <= Given.length(); i++) {
if (isdigit(Given[i])) {
for (int x = flag; x <= 1; x--) {
word += Given[i - x];
}
Display[(int)Given[i]] = word;
word = "";
flag = 0;
}
else {
flag++;
}
}
for (int z = 0; z <= 1; z++) {
cout << Display[z];
}
}
int main()
{
analyze();
system("pause");
return 0;
}
I'v included the <string> and <iostream> libraries and used namespace std.
For some reason, I can't figure out. Because I can't really understand exceptions, my code doesn't work and throws the following:
Exception thrown: write access violation. _My_data was 0x7001AC.
Any help would be appreciated.

You can easily track your error using a debugger. I strongly recommend learning how to use it.
But anyways, there are multiple things wrong with your code. In the first place, you should learn how does for loop work and how you should iterate over the string.
for (int i = 0; i <= Given.length(); i++)
should be
for (int i = 0; i < Given.length(); i++)
so instead <= you should use <. Because last element of string is stored on position n-1 if n is length, because you are iterating from 0.
Also in your inner loop
for (int x = flag; x <= 1; x--) {
you are iterating down, so you should be comparing x >= 1 instead of x <= 1.
Also (int)Given[i] returns an ASCII value of char stored in Given[i]. For example if Given[i]='0' then (int)Given[i] will return the ascii value of char '0', namely 48 and not 0 as you would think.
You can find more on this problem here: Convert char to int in C and C++.

For some reason, I can't figure out. Because I can't really understand
exceptions, my code doesn't work and throws the following
When you deal with string of numbers, would be nice to care about exceptions. For that you can use try and catch blocks, something like follows.
std::string strChar(1, it); Here I have converted each chars of the string and simply used std::stoi to convert it to an integer.
Since it is in the try block, if std::stoi fails to convert it to an integer, an exception will be through, which will be caught by the catch block given. There we will take care of the words which we need to print latter.
To make it in order, used std::sort() with a lambda function which will sort according to the integer in the Type declared as a pair of int and std::string.
See the Output: https://www.ideone.com/tSMu6q
#include <iostream>
#include <vector>
#include <algorithm>
#include <exception>
#include <string>
typedef std::pair<int, std::string> Type;
void analyze()
{
std::string Given = "there1hello0";
std::string word;
std::vector< Type > vec;
for(auto& it: Given)
{
int number;
std::string strChar(1, it);
try
{
number = std::stoi(strChar);
vec.emplace_back(std::make_pair(number, word));
word.clear();
}
catch(std::exception& e)
{
word += it;
}
}
std::sort(vec.begin(), vec.end(),
[](const Type& A, const Type& B)->bool
{
return A.first < B.first;
});
for(const auto& it: vec)
std::cout << it.second ;
std::cout << '\n';
}
int main()
{
analyze();
system("pause");
return 0;
}

Related

All of the option to replace an unknown number of characters

I am trying to find an algorithm that for an unknown number of characters in a string, produces all of the options for replacing some characters with stars.
For example, for the string "abc", the output should be:
*bc
a*c
ab*
**c
*b*
a**
***
It is simple enough with a known number of stars, just run through all of the options with for loops, but I'm having difficulties with an all of the options.
Every star combination corresponds to binary number, so you can use simple cycle
for i = 1 to 2^n-1
where n is string length
and set stars to the positions of 1-bits of binary representations of i
for example: i=5=101b => * b *
This is basically a binary increment problem.
You can create a vector of integer variables to represent a binary array isStar and for each iteration you "add one" to the vector.
bool AddOne (int* isStar, int size) {
isStar[size - 1] += 1
for (i = size - 1; i >= 0; i++) {
if (isStar[i] > 1) {
if (i = 0) { return true; }
isStar[i] = 0;
isStar[i - 1] += 1;
}
}
return false;
}
That way you still have the original string while replacing the characters
This is a simple binary counting problem, where * corresponds to a 1 and the original letter to a 0. So you could do it with a counter, applying a bit mask to the string, but it's just as easy to do the "counting" in place.
Here's a simple implementation in C++:
(Edit: The original question seems to imply that at least one character must be replaced with a star, so the count should start at 1 instead of 0. Or, in the following, the post-test do should be replaced with a pre-test for.)
#include <iostream>
#include <string>
// A cleverer implementation would implement C++'s iterator protocol.
// But that would cloud the simple logic of the algorithm.
class StarReplacer {
public:
StarReplacer(const std::string& s): original_(s), current_(s) {}
const std::string& current() const { return current_; }
// returns true unless we're at the last possibility (all stars),
// in which case it returns false but still resets current to the
// original configuration.
bool advance() {
for (int i = current_.size()-1; i >= 0; --i) {
if (current_[i] == '*') current_[i] = original_[i];
else {
current_[i] = '*';
return true;
}
}
return false;
}
private:
std::string original_;
std::string current_;
};
int main(int argc, const char** argv) {
for (int a = 1; a < argc; ++a) {
StarReplacer r(argv[a]);
do {
std::cout << r.current() << std::endl;
} while (r.advance());
std::cout << std::endl;
}
return 0;
}

cin strings into a vector and quicksort them

Write a void function called string_list_sort() that reads in any number of strings (duplicates are allowed) from cin, stores them in a vector, and then sorts them. Don’t use the standard C++ sort function here — use the version of quicksort that you created.
My problem is I tried to use strcmp() but I got a lot of errors, so I tried this method, but I have a problem with char val = v[end]. I am not sure how to compare two std::string values.
I changed char to string and it works. Now my problem is for example v = {" apple", "car", "fox", " soap", "foz"}; the result I get is apple, soap, car, fox, foz which is not in alphabetical order
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <vector>
#include "error.h"
using namespace std;
void string_list_sort(vector<string> v){
string line;
while (getline(cin, line)){
if (line.empty()){
break;
}
v.push_back(line);
}
}
int partition(vector<string>&v, int begin, int end)
{
char val = v[end];
char temp;
int j = end;
int i = begin - 1;
while (true)
{
while (v[++i] < val)
while (v[--j] > val)
{
if (j == begin)
break;
}
if (i >= j)
break;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
temp = v[i];
v[i] = v[end];
v[end] = temp;
return i;
}
void quicksort(vector<string>& v, int begin, int end)
{
if (begin < end)
{
int p = partition(v, begin, end);
quicksort(v, begin, p - 1);
quicksort(v, p + 1, end);
}
}
void quick_sort(vector<string>& v)
{
quicksort(v, 0, v.size() - 1);
}
int main()
{
vector<string> v;
v =
{ " this is a test string,.,!"};
string word;
while (cin >> word)
{
v.push_back(word);
}
quick_sort(v);
for (int i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
}
OP almost has a sorting function. Two mistakes in particular stand out:
char val = v[end];
char temp;
v is a vector<string> so v[end] will return a string.
string val = v[end];
string temp;
Takes care of that and makes the program compile and successfully sort. There is no need to go inside the strings to compare character by character. string does that work for you.
The second problem: Quicksort's partition function is supposed to look like (Looting from wikipedia here)
algorithm partition(A, lo, hi) is
pivot := A[lo]
i := lo – 1
j := hi + 1
loop forever
do
i := i + 1
while A[i] < pivot
do
j := j – 1
while A[j] > pivot
if i >= j then
return j
swap A[i] with A[j]
and OP's partition function has picked up a bunch of extra baggage that needs to be removed to get an optimal mark from their instructor. Take a look at the above pseudo implementation and compare it with yours. You may see the mistakes right way, but if not, stand on the shoulders of giants and translate it into C++ (hints: := is plain old = in C++, and you'll need to add some ;s and braces). Debug the result as required. I won't translate it because that would almost totally defeat the point of the assignment.
Side notes (gathering a few important comments):
When writing a test driver don't take in user input until you know the algorithm works. Start with preloaded input that is easy to visualize like
int main()
{
vector<string> v{"C","B","A"};
quick_sort(v);
for (size_t i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
}
When the output is "A B C ", change the input to something more complicated, but still easy to visualize
vector<string> v{"A","C","Q","B","A"};
And when that works go nuts and feed it something nasty. I like the Major General's Song from the Pirates of Penzance.
You can compare strings using std::string::compare() or relational operators.
It looks like you've tried using relational operators here, but as #user4581301 pointed out, in partition() on the first line, you have
char val = v[end];
However, v[end] is of type 'string', not 'char'. If you declare val and temp as string instead of char, you can sort them with the relational operators you have, and I think you'll be fine.
compare() documentation: fttp://www.cplusplus.com/reference/string/string/compare/
Relational operators: http://www.cplusplus.com/reference/string/string/operators/

Trouble with struct() and arrays C++

So, i have to do this project for college. I have to write a program that manages the orders of a pizza restaurant. so far this is what i have done :
#include <iostream>
#include <array>
#include <string>
#include <cctype>
#include <cmath>
#include <locale>
#include <algorithm>
using namespace std;
const int MAX_INGREDIENTES_PIZZA=10;
const int MAX_PEDIDOS=20;
enum TIngrediente
{
TOMATE,
QUESO,
NATA,
CEBOLLA,
POLLO,
HUEVO,
SALAMI,
ANCHOA,
BACON,
GAMBA
};
struct TPedido
{
string nombre_cliente;
int telefono;
int numero_pedido;
int numero_ingredientes;
TIngrediente ingredientes;
};
typedef array<float, MAX_PEDIDOS> listado_pedidos;
const array<string, MAX_INGREDIENTES_PIZZA> TIngredientes2 = {{"tomate", "queso", "nata", "cebolla", "pollo", "huevo", "salami", "anchoa", "bacon", "gamba"}};
TIngrediente StrToIngrediente(string s);
string IngredienteTostr(TIngrediente c);
string tolower(string s);
string tolower(string s)
{
string r = s;
for (int i = 0; i < s.size(); ++i)
r[i] = tolower(r[i]);
return r;
}
TIngrediente StrToIngrediente(string s)
{
s=tolower(s);
int i;
while (i < TIngredientes2.size() and TIngredientes2[i] != s)
++i;
return (TIngrediente)i;
}
string IngredienteTostr(TIngrediente c)
{
return TIngredientes2[c];
}
TIngredientes2 leer_ingrediente()
{
TIngredientes2 r;
for (int i=0; i<MAX_INGREDIENTES_PIZZA;i++){
cin>>r[i];
r[i]=tolower(r[i]);
}
StrToIngrediente(TIngredientes2);
return r;
}
TIngredientes2 escribir_ingrediente()
{
TIngredientes2 s;
for(int i=0; i<s.size(); i++){
cout<<s[i]<<endl;
}
return s;
}
TPedido leer_pedido()
{
TPedido p;
string ingredientes;
bool ok=true;
getline (cin, p.nombre_cliente);
cin >> p.telefono;
cin >> p.numero_pedido;
cin >> p.numero_ingredientes;
cin.ignore(100,'\n');
//getline (cin, p.ingredientes);
StrToIngrediente(ingredientes);
//necesitamos inicializar la variable booleana
if( numero_ingredientes > MAX_INGREDIENTES_PIZZA)
ok=false;
else if (numero_pedido > MAX_PEDIDOS)
ok=false;
else if (ingredientes != TIngrediente[i])
ok=false;
return p;
}
OK, But im having a few issues :
1) i have declared TIngredientes2 as an array, but the compiler says to me Tingredientes2 does not name a type.
2) I have managed to write the functions that transforms String in TIngrediente (enum) and viceversa, but now i have to make 2 functions to read keyboard input/write in screen and i dunno how to use those functions. I have writen something below but i dont know if it is ok.
3) When it comes to read keyboard input in leer_pedido() i dont know if that is ok because of the struct and most important, i have no idea how to use the boolean to say if the data introduced is correct or not.
4) The next fuction consist in storing the data from the last fucntion leer_pedido() in a list, and i have no clue.
I hope someone can help me
1) Function can't return an object of type 'Ttingrediente2' if you haven't already made class of type 'Tingrediente2'.
In your function :
TIngredientes2 escribir_ingrediente()
{
TIngredientes2 s;
for(int i=0; i<s.size(); i++){
cout<<s[i]<<endl;
}
You're declaring variable 'Tingredientes s' and after it,you're printing it out on the screen but it hasn't got size (there are no elements inside s).
Try like this:
void escribir_ingrediente(array<string,MAX_INGREDIENTES_PIZZA> s)
{
for(int i=0; i<s.size(); i++)
cout<<s[i]<<endl;
}
where you are passing already existing array to a function and it's printing out elements of s array.
2) Just read more about enumerations,iterating over them and inserting new elements.
3) You're using boolean variable on the beginning of testing your user's input.Something like:
bool good_Input = true; // suppose user's input is ok
if( p.numero_ingredientes > MAX_INGREDIENTES_PIZZA || p.numero_pedido > MAX_PEDIDOS)
good_input=false; // input is not good if there is more ingredients than max number of ingredients
if(good_Input)
cout<<"Input is good"<<endl;
else cout << "Input is not good"<<endl;
Therefore,you are leading boolean variable through your code so if there may be a mistake,you change it's value to 'false' and it will be 'false' to the end so you will know how to handle it further in code.
4) Storing structure's data in vector is the most easiest way to do that:
vector<Tpedido> structuresVector;
sturcturesVector.push_back(leer_pedido());
leer_pedido function returns 'Tpedido' type so you can insert it in vector directly

how to import text file into structs C++

I'm trying to import data from a text file into structs for use as i don't really want to import them into seperate arrays.
I keep getting "error: expected primary-expression before '[' token" on each getline, i'm terrible at C++ and basically using what C skills i have to try and make sense of this. What am i doing wrong?
#include <stdio.h>
#include<fstream>
#include <cstdlib>
#include <iostream>
#include "Ladybird.h"
using namespace std;
typedef struct managerImport{
int gridSizeA;
int gridSizeB;
int aphidCount;
int aphidPos;
int ladyCount;
int ladyPos;
struct managerImport *next;
};
void importData(managerImport[]){
ifstream manager;
manager.open("Manager.txt");
if (!manager.fail()){
//loops the 2d array
for (int i = 0; i < 1; i++)
{
getline(manager, managerImport[i].gridSizeA, managerImport[i].gridSizeB);
}
//loop the lady bird count
for (int i = 1; i < 2; i++)
{
getline(manager, managerImport[i].ladyCount);
}
//loops the lady bird coordinates
for (int i = 2; i < 10; i++)
{
getline(manager, managerImport[i].ladyPos);
}
for (int i = 10; i < 11; i++)
{
getline(manager, managerImport[i].aphidCount);
}
//loops the lady bird coordinates
for (int i = 11; i < 19; i++)
{
getline(manager, managerImport[i].aphidPos);
}
}
manager.close();
}
int main() {
//importing the manager text file
importData;
}
Did you name the argument in the function?
void importData(managerImport[]) just says you have a function importData that takes an array of type managerImport (your struct).
Edited for clarification:
Imagine I write this code:
int increment(int) { return int+1; }
What I've done is hand the compiler a function that takes an argument "int". Is "int" a type or the name of my argument? This obviously won't compile since the argument has to have both a type and a name (so even if I want want to name my argument "int" (not advised), I still need to supply a type which says what "int" actually is (type-wise). Is it a long, a string, an unsigned char? Assuming I meant to actually accept an int, add 1, and return the incremented value (an int), this is what I should have written:
int increment(int i) { return i+1; }
So, in your case, you have:
void importData(managerImport[]) { ... }
Obviously, you're meaning to accept an array of managerImport, but you haven't given that array a name. Try this:
void importData(managerImport foo[]) { .. }
Also, unless you really need a c-array, you might try using a vector or an C++ array (std::array).
The function getline does not translate text into integers. It simply copies text without translations.
for (int i = 0; i < 1; i++)
{
getline(manager, managerImport[i].gridSizeA, managerImport[i].gridSizeB);
}
Your getline function call translates to getline(stream, int, int);.
You will need to either use:
manager >> managerImport[i].gridSizeA >> managerImport[i].gridSizeB;
or read in as string and parse out of the string.

deleting some characters from string and copying it

I am trying to delete characters that aren't numbers nor letters from a string by such a stupid method since I failed in getting other methods ( I am a real beginner "just trying ")
I know that this way isn't the right one but my question is what the problem with it what is the error since it doesn't work :S
string g = "9-=p98u;iu8y76";
string y;
int t = 0;
for (int i = 0; i < g.length(); i++)
{
if (isdigit(g[i]) || isalpha(g[i]))
{
y[t++] = g[i];
}
else
continue;
}
g = y;
cout << g;
The problem is that the size of y is 0, it's empty. Accessing its elements (using y[t++]) therefore reaches "after" the string—it's buffer overflow, and Undefined Behaviour.
You need to extend y. To do this with minimal changes to your code, you'd do this:
string g = "9-=p98u;iu8y76";
string y;
for (int i = 0; i < g.length(); i++)
{
if (isdigit(g[i]) || isalpha(g[i]))
{
y.push_back(g[i]);
}
else
continue;
}
g = y;
cout << g;
Of course, there are other ways to do that. Using standard algorithms and the erase-remove idiom would be more idiomatic C++. The entire code can be replaced with this:
auto shouldBeRemoved = [](char c) { !(isdigit(c) || isalpha(c)) };
g.erase(std::remove_if(g.begin(), g.end(), shouldBeRemoved), g.end());
cout << g;
std::remove_if works by reorganising the range so that all elements which match the predicate (i.e. those which should be removed) are moved after all elements which are to remain. The member function erase then erases all of those which were moved to the back.
This is reasonably expressed by the standard library. Something like
auto digit_or_alpha = [](char c){ return isdigit(c) || isalpha(c); };
std::copy_if(g.begin(), g.end(), std::back_inserter(y), digit_or_alpha );
Should work. back_inserter is in <iterator>. Angew provides the reason why yours doesn't work.
The problem is the way you are trying to extend the string y. Indexing can be applied only in the domain of the string (i.e. you cannot index beyond the length of the string)
change y[t++] = g[i] to y += g[i]
Additionally, i would like to mention that you don't need the else branch. When execution reaches the end of loop scope, it will "automatically" continue, it isn't needed to be expressed explicitly.
PS: It's classic C++, not C++11, I would accept Captain Giraffe's answer
The general approach for such tasks is to use member function erase along with standard algorithm std::remove_if declared in header <algorithm>
For example
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main()
{
std::string s = "9-=p98u;iu8y76";
std::cout << s << std::endl;
s.erase( std::remove_if( s.begin(), s.end(),
[]( char c )
{
return !std::isalnum( ( unsigned char )c );
} ),
s.end() );
std::cout << s << std::endl;
return 0;
}
The program output is
9-=p98u;iu8y76
9p98uiu8y76
As for your code then you are trying to use the subscript operator
y[t++] = g[i];
for an empty string
string y;
Take into acoount that instead of two functions std::isalpha and std::isdigit you can use one function std::isalnum as shown in my demonstrative program.
If you want to write loops yourself then the program can look like
#include <iostream>
#include <string>
#include <cctype>
int main()
{
std::string s = "9-=p98u;iu8y76";
std::cout << s << std::endl;
std::string::size_type i = 0;
while ( i < s.length() && std::isalnum( ( unsigned char )s[i] ) ) ++i;
std::string::size_type j = i;
while ( i++ < s.length() )
{
if ( std::isalnum( ( unsigned char )s[i] ) ) s[j++] = s[i];
}
s.erase( j );
std::cout << s << std::endl;
return 0;
}
The program output is the same as above
9-=p98u;iu8y76
9p98uiu8y76
There is no need to use an additional string to do this operation.

Resources