Error with strtok Function - c++

In my code i get a unhandled expression error when i use parse function.
In my PopStack function is this the right way to delete the last element of vector.
Error is:
Unhandled exception at 0x0f463b50 (msvcr100d.dll) in Boost_Test.exe: 0xC0000005: Access violation writing location 0x00345d49.
class Stack
{
public:
Stack() {GlobalIndex=0; };
std::vector<char*> v;
int GlobalIndex;
void AddStack(char* txt);
void Parse();
void PopStack();
void PrintStack();
};
void Stack::Parse()
{
char* tok;
tok = strtok(v[GlobalIndex-1], ";");
while(tok!=NULL)
{
cout<<"\nThe time value is = "<<tok<<endl;
tok = strtok(NULL, " ");
}
}
void Stack::AddStack(char* txt)
{
v.push_back(txt);
GlobalIndex++;
}
void Stack::PopStack()
{
v.pop_back();
GlobalIndex--;
}
void Stack::PrintStack()
{
std::cout<<v[GlobalIndex-1]<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int i;
Stack s;
s.AddStack("aaa;1.2");
s.AddStack("bbb;1.7;");
s.AddStack("ccc;2.2");
s.Parse(); // This gives a unhandled expression error
s.PopStack();
s.PrintStack();
return 0;
}

The end of the token found, in you case the ';', is replaced by a 0.
This write operation is done on the string literal you pass:
s.AddStack("aaa;1.2");
But the literal is not writable, basically its a 'const char *', hence the access violation.

As advised by other members i have now used c++ strings along with boost library.
#include "stdafx.h"
#include <iostream>
#include <asio.hpp>
#include <regex.hpp>
#include <algorithm/string/regex.hpp>
#include <string>
#include <algorithm/string.hpp>
using namespace std;
class Stack
{
public:
Stack() {GlobalIndex=0; };
std::vector<std::string> v;
string s;
int GlobalIndex;
void AddStack(std::string);
void Parse();
void PopStack();
void PrintStack();
};
void Stack::Parse()
{
std::vector<std::string> result;
boost::split(result,v[GlobalIndex-1],boost::is_any_of(";"));
cout<<"\nThe boost split is = "<<result[1]<<endl;
}
void Stack::AddStack(std::string txt)
{
v.push_back(txt);
GlobalIndex++;
}
void Stack::PopStack()
{
v.pop_back();
cout<<v.size()<<endl;
GlobalIndex--;
}
void Stack::PrintStack()
{
std::cout<<v[GlobalIndex-1]<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int i;
Stack s;
s.AddStack("aaaaaa;1.2");
s.AddStack("bbbbb;1.7;");
s.AddStack("ccccc;2.2");
s.Parse();
s.PopStack();
s.PopStack();
s.PrintStack();
cin>>i;
return 0;
}

Related

My C++ attempt to convert std::vector<std::string> to JSON doesn't compile

I am trying to port a program I've written in JavaScript to C++ to make it faster. In that program, I dealt somewhat with JSONs. So, I tried to make a method for converting a vector of strings into JSON:
#include <iostream>
#include <vector>
#include <string>
class std::vector<std::string> {
public: std::string JSON();
};
std::string std::vector<std::string>::JSON() {
std::string ret="[";
if (this->size()==0) {
ret+="]";
return ret;
}
int currentSize=this->size();
for (int i=0; i<currentSize; i++) {
if (i!=currentSize-1)
ret+="\""+this->operator[](i)+"\",";
else
ret+="\""+this->operator[](i)+"\"]";
}
return ret;
}
int main(int argc, char **argv) {
std::vector<std::string> fieldOfStrings({"Hello","world","!"});
std::cout <<fieldOfStrings.JSON() <<std::endl;
return 0;
}
However, it doesn't compile:
/home/teo.samarzija/Documents/AECforWebAssembly/AECforWebAssembly.cpp:5:12: error: too few template-parameter-lists
class std::vector<std::string> {
^
/home/teo.samarzija/Documents/AECforWebAssembly/AECforWebAssembly.cpp:9:13: error: specializing member 'std::vector<std::basic_string<char> >::JSON' requires 'template<>' syntax
std::string std::vector<std::string>::JSON() {
What am I doing wrong? I am fairly new to C++.
First, the class std::vector<std::string> does not make sense. Second, a class is not necessary since you can just define a function similar to your member function that takes in std::vector<std::string> and return the json string.
For example:
#include <iostream>
#include <vector>
#include <string>
std::string JSON(std::vector<std::string> str) {
std::string ret="[";
if (str.size()==0) {
ret+="]";
return ret;
}
int currentSize=str.size();
for (int i=0; i<currentSize; i++) {
if (i!=currentSize-1)
ret+="\""+str[i]+"\",";
else
ret+="\""+str[i]+"\"]";
}
return ret;
}
int main(int argc, char **argv) {
std::vector<std::string> fieldOfStrings({"Hello","world","!"});
std::cout <<JSON(fieldOfStrings) <<std::endl;
return 0;
}
As mentioned above the easiest way is a free function.
std::string JSON(std::vector<std::string>& vec) {
std::string ret="[";
if (vec.size()==0) {
ret+="]";
return ret;
}
int currentSize=vec.size();
for (int i=0; i<currentSize; i++) {
if (i!=currentSize-1)
ret+="\""+vec[i]+"\",";
else
ret+="\""+vec[i]+"\"]";
}
return ret;
}
And call it like
std::cout << JSON(fieldOfStrings) <<std::endl;

Printing vector out in functions

I need to print the vector i have filled in listInput. When i go to listPrint the program crashes. What can i do to fix it? Here is my main:
#include <iostream>
#include <string>
#include <vector>
#include "func.h"
using namespace std;
int main(int argc, char** argv) {
subjects a;
int r=1;
while(r!=0){
int select=a.userChoice();
switch(select){
case 1:
a.listPrint();
break;
case 2:
listInput(a);
break;
}
}
return 0;
}
My header:
#ifndef SUBJECT
#define SUBJECT
#include <string>
#include <vector>
class subjects{
private:
std::string subjectName;
std::string lectName;
std::string lectSurname;
int credits;
int studentnum;
public:
/* subjects(){
subjectName="";
lectName="";
lectSurname="";
credits=0;
studentnum=0;
}*/
int userChoice();
int enterNumber(std::string name);
void menu();
std::string getSubjectName(){
return subjectName;
}
std::string getLectName(){
return lectName;
}
std::string getLectSurname(){
return lectSurname;
}
int getCredits(){
return credits;
}
int getStudentNum(){
return studentnum;
}
friend void listInput(subjects a);
void listPrint();
bool checkName(std::string &text);
std::vector<subjects*> entry;
subjects(const std::string subjectName="", const std::string lectName = "", const std::string lectSurname="", const int credits = 0, const int studentnum = 0) :
subjectName(subjectName),
lectName(lectName),
lectSurname(lectSurname),
credits(credits),
studentnum(studentnum){
}
};
#endif
And my function file:
void listInput(subjects a){
.
.
.
a.entry.push_back(new subjects(a.subjectName, a.lectName,a.lectSurname,a.credits, a.studentnum));
}
void subjects::listPrint(){
for(int i=0; i<entry.size(); i++){
cout<<entry[i]->getSubjectName()<<" "<<entry[i]->getLectName()<<" "<<entry[i]->getLectSurname()<<" "<<entry[i]->getCredits()<<" "<<entry[i]->getStudentNum()<<endl;
}
}
I know that using friend functions arent recommended, but i am required to use atleast one of them. Also if i print the vector in listInput, then it only prints the first entry. If there is more than one entry in the vector, it also crashes.
You pass the a instance by value to the list function and then you try to print it. You should consider passing it by reference if you plan to use it outside the scope of the list function.

Unhandled exception at 0x00de1818 in 2.exe: 0xC0000005: Access violation writing location 0xcd7cbe10

Here is my program
Contact.h
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
#pragma once
class Contact
{
private:
char *Name;
char *Last;
int Phone;
char *Address;
public:
Contact operator +(Contact NewVal);
Contact(char *newName,char *newLastName,char *newAddress,int newPhone);
Contact(void);
~Contact(void);
void SetName(char *newName);
void SetLastName(char *newLastName);
void SetAddress(char *newAddress);
void SetPhone(int newPhone);
char* Contact::GetLast(void);
char* Contact::GetAddress(void);
int Contact::GetPhone(void);
char* GetName(void);
};
Contact.cpp
#include "StdAfx.h"
#include "Contact.h"
Contact::Contact(void)
{
}
Contact::Contact(char *newName,char *newLastName,char *newAddress,int newPhone)
{
SetName(newName);
SetLastName(newLastName);
SetAddress(newAddress);
SetPhone(newPhone);
}
Contact::~Contact(void)
{
}
void Contact::SetName(char *newName){
Name=_strdup(newName);
}
void Contact::SetLastName(char *newLastName){
Last=strdup(newLastName);
}
void Contact::SetAddress(char *newAddress){
Address=strdup(newAddress);
}
void Contact::SetPhone(int newPhone){
Phone=newPhone;
}
char* Contact::GetName(void)
{
return Name;
}
char* Contact::GetLast(void)
{
return Last;
}
char* Contact::GetAddress(void)
{
return Address;
}
int Contact::GetPhone(void)
{
return Phone;
}
Contact Contact::operator+(Contact NewVal)
{
//strcat(this->Address,NewVal.Address);
//strcat(this->Last,NewVal.Last);
//strcat(this->Name,NewVal.Name);
this->Phone=this->Phone+NewVal.Phone;
sprintf(this->Address,"%s %s",this->Address,NewVal.Address);
sprintf(this->Name,"%s %s",this->Name,NewVal.Name);
sprintf(this->Last,"%s %s",this->Last,NewVal.Last);
return *this;
}
Phonebook.h
#include "Contact.h"
#pragma once
class PhoneBook
{
private:
Contact member[100];
int ID;
public:
PhoneBook(void);
~PhoneBook(void);
Contact Search(char* newName);
bool AddNewContact(char* NewName, char* NewLast, char* NewAddress,int NewPhone);
void ShowContacts(void);
};
PhoneBook.Cpp
#include "StdAfx.h"
#include "PhoneBook.h"
PhoneBook::PhoneBook(void)
{
}
PhoneBook::~PhoneBook(void)
{
}
Contact PhoneBook::Search(char* newName)
{
return Contact();
}
bool PhoneBook::AddNewContact(char* NewName, char* NewLast, char* NewAddress,int NewPhone)
{
ID=ID+1;
member[ID].SetName(NewName);
member[ID].SetLastName(NewLast);
member[ID].SetAddress(NewAddress);
member[ID].SetPhone(NewPhone);
return true;
}
void PhoneBook::ShowContacts(void)
{
for(int a=0;a<=ID;a++){
cout<<"Name:"<<member[ID].GetName()<<endl<<"LastName:"<<member[ID].GetLast()<<endl<<"Address:"<<member[ID].GetAddress()<<endl<<"Phone:"<<member[ID].GetPhone()<<endl;
}
}
After executing these lines I get access violation error(for SetName function)
int _tmain(int argc, _TCHAR* argv[])
{
PhoneBook mem;
mem.AddNewContact("Bob","Jones","LA",100);
return 0;
}
However this code works fine!!! it means Set functions in Contact.h file work without any problems but after adding the Phonebook class it won't work.
int _tmain(int argc, _TCHAR* argv[])
{
PhoneBook mem;
Contact no("Bob","Jones","LA",100);
//mem.AddNewContact("Bob","Jones","LA",100);
return 0;
}
I will be grateful if you can help me.
Sorry for my mistake. I've forgotten to set a default value for ID variable.
Thanks Steve and Gray for your comments.

terminate called after throwing an instance of 'std::invalid_argument' what(): dataItem already in tree Abort (core dumped)

I'm getting the error
terminate called after throwing an instance of
'std::invalid_argument'what(): dataItem already in tree Abort (core
dumped)
i've tried everything and i can't think of anything to possibly fix this i'm assuming im storing the tree when its already stored but i have no idea, any help would be appreciated
Below is my Code - i also use bintree and binNode :
#include <iostream>
#include <string>
#include <ctype.h>
#include <fstream>
#include <stdlib.h>
#include "bintree.h"
#include "binnode.h"
using namespace std;
class mazePoint
{
private:
int x;
char pointType;
public:
void setPointMaze(char ch, int i)
{
pointType = ch;
x = i;
}
bool operator == (const mazePoint &other) const
{
return(this->x == other.x);
}
bool operator < (const mazePoint &other) const
{
return(this->x < other.x);
}
};
class mazeRow
{
private:
bintree<mazePoint> points;
int y;
public:
void setMazeRow(int rowNumber)
{
y = rowNumber;
}
bool operator==(const mazeRow &other) const
{
return(this->y < other.y);
}
bool operator<(const mazeRow &other) const
{
return(this->y < other.y);
}
void storePointMaze(char ch, int i)
{
mazePoint point;
point.setPointMaze(ch,i);
points.insert(point);
}
void incrementeRow()
{
y++;
}
};
void loadMaze(bintree<mazeRow> &maze, const char *filein, int argc);
int main (int argc, char* argv[])
{
unsigned int start = 0;
unsigned int finish = 0;
bintree<mazeRow> maze;
string filein;
loadMaze(maze, argv[1], argc);
return 0;
}
void loadMaze(bintree<mazeRow> &maze, const char *filein, int argc)
{
if ( argc < 2) {
cout << "Must supply 1 argument to this program";
exit(0);
}
mazeRow row;
ifstream infile(filein);
char temp;
unsigned int i = 0;
if (infile.is_open() && infile.good()) {
while (!infile.eof())
{
infile.get(temp);
i++;
row.storePointMaze(temp, i);
if(temp == '\n') ./
{
maze.insert(row);
row.incrementeRow();
}
}
}
else {
cout << "Failed to open file..";
}
infile.close();
}
Thank you
The error message indicates that there is an exception being thrown that is not caught in your code. This is most probably being thrown in binTree implementation, when you try to insert an element whose key is already in?
You can use a debugger to break at the point where the exception is thrown (in gdb catch throw would be the command) and you can then inspect why you ended up in this situation.

C++ VALGRIND Uninitialised value was created by a heap allocation

I have a problem. When I compile the program I don't have any errors, but when I use valgrind:
Uninitialized value was created by a heap allocation (line with new)
Conditional jump or move depends on uninitialized value(s)(line with delete)
I search through the forums however I didn't find much information which could help me.
I would be really grateful for a hint.
My program
#include <cstdlib>
#include <stdint.h>
#include <cstdio>
#include <iostream>
#include <string>
#include <istream>
#include <cstring>
#include <fstream>
#include <sstream>
#include <cctype>
using namespace std;
using std::cout;
using std::endl;
int dlugosc,miejsce;
ifstream file;
class channel
{
public:
int start;
double length;
int bytespix;
int resolution;
channel(double g) : start(g),
length(0),
bytespix(0),
resolution(0)
{
}
};
int fileopen() // opens the file and returns its size
{
file.open ("0_dlc.000", ios::in|ios::binary);
if( file.good() == true )
{
cout << "Uzyskano dostep do pliku!" << endl;
}
else
{
cout<< "File cannot open" <<endl;
}
file.seekg(0, file.end);
dlugosc = file.tellg();
return dlugosc;
}
int findword(const char* slowo,int startplace)
{
int m;
int c=0;
int cur=0;
unsigned int equal=0;
char element=0;
file.seekg (startplace, file.beg);
for(m=0;m<dlugosc;m++)
{
file.get(element);
if(element==slowo[cur])
{
equal++;
cur++;
}
else
{
equal=0;
cur=0;
if(element==slowo[cur])
{
equal++;
cur++;
}
}
if(equal==strlen(slowo))
{
return m+startplace;
}
}
return 0;
}
int findvalue(const char* wartosc,int startpoint)
{
int p;
int g;
char element=0;
char* buffer = new char[9];
miejsce = findword(wartosc,startpoint); // miejsce to global variable
file.seekg (miejsce+1, file.beg);
for(p=0;(int)element<58;p++)
{
file.get(element);
if((int)element>58 || (int)element<48)
break;
else
buffer[p] = element;
}
buffer[p]='\0';
g = atoi(buffer);
delete [] buffer;
return g;
}
int main()
{
int a,h=0,channels,start=0,length=0,resolution=0,bytespix=0,m=0;
const char* slowko="Data offset: ";
dlugosc=fileopen();
channel** kanaly=0;
kanaly = new channel*[9];
miejsce=0;
for(a=0;a<9;a++)
{
kanaly[a] = new channel(4);
start = findvalue("Data offset: ",miejsce+20);
kanaly[a]->start=start;
}
for(m=0;m<9;m++)
{
delete kanaly[m];
}
delete []kanaly;
file.close();
}
The problem is in the constructor of channel. Initialize all member variables, and the problem will go away :
class channel
{
public:
double start;
double length;
int bytespix;
int resolution;
channel(double g) : start(g),
length(0),
bytespix(0),
resolution(0)
{
}
};