works in debugger mode. Crashes in executable mode - c++

The code was written in VS community 2013. The program worked fine in debugger mode. But crashed while execution. Please let me know what could be the problem.
sample test case:
10
aaa
bbb
ccc
aaa
The program crashed at 3rd input line, sometimes at 4th input line.
#include<iostream>
#include<string.h>
#include<string>
using namespace std;
class registeration
{
public:
char* name;
int count;
registeration *next;
registeration()
{
name = new char(20);
count = 0;
next = NULL;
}
};
int main()
{
int n;
cin >> n;
char* str = new char(n);
registeration *regStart = new registeration();
while (n--)
{
cin >> str;
if (regStart->next == NULL)
{
registeration *reg = new registeration();
regStart->next = reg;
reg->count++;
//strcpy(reg->name, str);
strcpy_s(reg->name, 20, str);
}
else
{
registeration *reg = new registeration();
reg = regStart->next;
while (reg->next != NULL && strcmp(str, reg->name))
{
//registeration *reg1 = new registeration();
reg = reg->next;
}
if (!strcmp(str, reg->name))
reg->count++;
else
{
registeration *reg1 = new registeration();
strcpy_s(reg1->name, 20, str);
reg1->count++;
reg->next = reg1;
}
}
}
registeration *reg = new registeration();
reg = regStart->next;
while (reg != NULL)
{
if (reg->count > 1)
cout << reg->name << endl;
reg = reg->next;
}
return 0;
}

One obvious bug is in these lines:
name = new char(20);
char* str = new char(n);
They allocate a single character initialized to the given value. Instead you intend to allocate an array of characters, which you do as follows:
name = new char[20];
char* str = new char[n];
(With bracket instead of parentheses.)
It is better though to use the standard C++ utilities that manage the memory for you, like std::string for strings and std::vector or std::list for the containers.
EDIT: This code does the same thing as yours, better:
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
int n;
cin >> n;
map<string, int> m;
for(int i = 0; i < n; ++i)
{
string s;
cin >> s;
m[s]++;
}
for(const auto &pr : m)
if(pr.second > 1)
cout << pr.first << '\n';
}

Related

Read access violation when compiling c++ code

I am trying to use pointer in reading string array,but it occurs an exception.
Here is the code:
#include<vector>
#include<string>
#include<iostream>
using namespace std;
int countn = 1;
class Solution {
public:
string findPrefix(string compa, string& compb,int n) {
string prefixi;
for (int i = 0; i < compa.length(); i++) {
if (compa[i] == compb[i]) {//Exception occurs here
prefixi.push_back(compa[i]);
}
else break;
}
countn++;
string* nxt = &compb;
nxt++;
if (countn<=n) {
prefixi = findPrefix(prefixi,*nxt,n);
}
return prefixi;
}
string longestCommonPrefix(vector<string>& strs) {
int n = strs.size();
string prefix;
prefix = findPrefix(strs[0], strs[countn],n);
return prefix;
}
};
int main() {
vector<string> str = { "flower", "fly","flip"};
Solution test;
string ans = test.longestCommonPrefix(str);
cout << ans << endl;
}
Exception occurs in line13
Then I checked the auto box and to find that the pointer nxt is pointing to the last string in str vector(string"filp"), I wonder if the pointer is out of boundary, but I do not know how to fix it and make my code work. Help me plz.

Repeated Function call in the following program in C++

I have to write a programs that takes an input of string which has some '$' and digits. The output of the program is set of all possible strings where the '$ in the string is replaced by all the other digits.
I have written the following code for it.
#include<bits/stdc++.h>
using namespace std;
int numberOf(string in)
{
int count = 0;
for(int i = 0; i <= in.size()-1; i++)
if(in[i] == '$')
count++;
return count;
}
void solve(string in, string in1, vector <string> &s,
int index)
{
if(numberOf(in) == 0)
{
s.push_back(in);
return;
}
if(index == in.size())
{
return;
}
if(in1.empty())
{
return;
}
else
{
if(in[index] == '$')
{
string in2 = in;
in2[index] = in1[0];
string in3 = in1;
in3.erase(in3.begin());
solve(in2, in1, s, index+1);
solve(in, in3, s, index);
return;
}
else
{
solve(in, in1, s, index+1);
return;
}
}
}
void replaceDollar(string in)
{
string in1 = in;
int count = 0;
for(int i = 0; i <= in.size()- 1; i++)
{
if(in[i] != '$')
{
in1.push_back(in[i]);
count++;
}
}
count = in.size() - count;
cout << "Number is " << count << "\n";
vector <string> s;
solve(in, in1, s, 0);
for(auto i = s.begin(); i != s.end(); i++)
cout << *i << " ";
cout << "\n";
}
int main()
{
int t;
cin >> t;
while(t--)
{
string in;
cin >> in;
replaceDollar(in);
}
return 0;
}
For following input
1
$45
The expected output should be
445 545
But it returns
445 545 445 545
Can anyone please explain why is it outputting repeated strings?
Also can anyone suggest a better approach to this question?
Thanks in advance!
Assuming that this is homework:
Start over. Your code is way too complex for this problem.
I would treat everything as type char
Loop/iterate over said string, using std::string::replace() to replace each instance of $ with each digit.
-- If your teacher doesn't want you using std libraries, then add another loop and compare yourself.
3a. Of course, add a check, so that you don't replace $ with $
Create a new copy of the string on each iteration.
Print each to stdout as you create them.
See this post:
How to replace all occurrences of a character in string?
p.s. Pro tip: don't use using namespace. Use the full namespace in your calls; e.g.:
Bad
using namespace std;
string = "hello world";
Good
std::string = "hello world";

C++ std::sort function gets not finished?

im currently setting up the highscore-part for a game and I have a very weird problem because of the weird behaviour of the std::sort function.
Im doing the whole thing in RAD Studio 10.2 (Embarcadero IDE) in C++.
So he is my code:
std::string Line;
int count = 0;
int i = 0;
ifstream File("Highscore.txt");
if(File.is_open())
{
while(getline(File, Line))
{
count += 1;
}
File.close();
}
ifstream ReadFile("Highscore.txt");
if(ReadFile.is_open())
{
string *scores = NULL;
scores = new string[count];
while(getline(ReadFile, Line))
{
scores[i] = Line;
i += 1;
}
ReadFile.close();
std::sort(scores, (scores+count));
UnicodeString Uscores1 = scores[0].c_str();
UnicodeString Uscores2 = scores[1].c_str();
UnicodeString Uscores3 = scores[2].c_str();
UnicodeString Uscores4 = scores[3].c_str();
UnicodeString Uscores5 = scores[4].c_str();
LScore1->Caption = Uscores1;
LScore2->Caption = Uscores2;
LScore3->Caption = Uscores3;
LScore4->Caption = Uscores4;
LScore5->Caption = Uscores5;
}
I get no errors from the compiler/linker and everything work should fine.
The string array gets filled correctly and so on.
But its not sorting.
To show the problem to you I made a screenshot - on the left you can see the txtfile with the scores; on the right you can see the output after the sorting algorithm:
My question now is why this is happening?
Thanks for you help
Welcome to C++. Since you want to list numbers by rank, read them as int not string. Forget about operator new. You will not need it for years, if ever. Use standard containers like std::vector, which take care of the memory allocation and de-allocation transparently.
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
int main() {
using namespace std;
vector<int> scores;
{
ifstream inp("Highscore.txt");
int next;
while (inp >> next) {
scores.push_back(next);
}
}
sort(scores.begin(), scores.end());
for (auto s : scores) {
cout << s << '\n';
}
return 0;
}
How about something like:
int i = 0;
int * scoresInteger = NULL;
scoresInteger = new int[count];
for(i = 0; i < count; i++)
{
scoresInteger[i] = std::stoi(scores[i]);
}
std::sort(scoresInteger, scoresInteger + count);
If you need to, you can convert the integers back into strings using targetStrings[i] = std::to_string(scoresInteger[i]).
string * targetScores = NULL;
targetScores = new std::string[count];
for(i = 0; i < count; i++)
{
targetScores[i] = std::to_string(scoresInteger[i]);
}
delete [] scoresInteger;
scoresInteger = NULL;
Don't forget to delete [] targetScores later.
My question now is why this is happening?
Because your scores are compared as strings and not as ints. Because of that "3" is greater that "25"
std::cout << std::boolalpha << (std::string("3") > std::string("25")) << std::endl; // true
Luckily you can pass a custom comparator (or lambda) to the std::sort to make it behave just as you want:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
const int count = 5;
std::string scores[count] = { "35","25","3","4","5" };
// TWEAKED SORT
std::sort(scores, scores + count, [](std::string const &s1, std::string const &s2)
{
return std::stoi(s2) < std::stoi(s1);
});
// TEST
for (auto const &s : scores)
{
std::cout << s << std::endl;
}
}
The compared strings in the above example are converted to ints and then compared, resulting in the desired sorting order.
35
25
5
4
3
Please note that I do not agree with the rest of your code and I think you should rethink the implementation, as it would be much easier, safer and more efficient to use std::vector<std::string> for your task.

Returning string from a function causing formatting issues

It's supposed to look like this: http://i.imgur.com/gko501E.png
Instead it looks like this: http://i.imgur.com/ISwqyD8.png
When I take the code out of the function and use it in the main class it works properly. However once I put it in this function the formatting problems occur, it also isn't filtering like it's supposed to. This program is supposed to take user input, store it in a string, remove all non-alphabetical characters, capitalize the vowels, and then space it out based on user defined variables given in the command line. It's also supposed to accept files as input in the command line, such as: 'program 5 8 < file'.
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <cstdlib>
#include <fstream>
#include <sstream>
using namespace std;
//make vowels uppercase
string filter(string input)
{
size_t found = input.find_first_of("aeiou");
while (found != string::npos)
{
if (islower(input[found]))
{
input[found] = toupper(input[found]);
found = input.find_first_of("aeiou", found + 1);
}
}
//Make consonants lowercase
size_t foundLower = input.find_first_of("BCDFGHJKLMNPQRSTVWXYZ");
while (foundLower != string::npos)
{
if (isupper(input[foundLower]))
{
input[foundLower] = tolower(input[foundLower]);
foundLower = input.find_first_of("BCDFGHJKLMNPQRSTVWXYZ", foundLower + 1);
}
}
//remove punctuation
for (int i = 0, len = input.size(); i < len; i++)
{
if (!isalnum(input[i]))
{
input.erase(i--, 1);
len = input.size();
}
}
return input;
}
int main(int argc, char* argv[])
{
int wordSize;
int wordSizeCounter;
int wordCounter = 0;
int rowSize;
//char letter;
wordSize = atoi(argv[1]);
rowSize = atoi(argv[2]);
ifstream inFile;
inFile.open(argv[3]);//open the input file
stringstream strStream;
strStream << inFile.rdbuf();//read the file
string test = strStream.str();//str holds the content of the file
if (!inFile) test = cin.get() ; // Read first character
//Begin filter for files
while (!test.empty())
{
filter(test);
if (test.length() < wordSize) //make sure we don't go out-of-bounds
{
wordSize = test.length();
}
cout << test.substr(0, wordSize);
cout << " ";
if (test.length() >= wordSize) //again, make sure we don't go out-of-bounds
{
test = test.substr(wordSize);
}
else
{
test = " ";
}
wordCounter++;
if (wordCounter == rowSize)
{
cout << std::endl;
wordCounter = 0;
}
if(test.empty())
{
test = cin.get();
}
}
cout << endl;
return 0;
}

Cutting a string into pieces

How can I extract pieces from this string?
I have a file that contains:
0065445 APPLE$456
089464 MANGO$489
0012389 GUAVA$744
What I want to do is input the file line by line, then cut the string into some pieces.
0065455 Will go in a struct a[0].num
APPLE will go in struct a[0].name
456 will go in struct a[0].dollar
And similarly for other lines.
Everything is working fine, but it's not successfully getting the dollar part into its variable.
Here's the code:
#include<cstdlib>
#include<iostream>
using namespace std ;
int main(){
FILE *fp;
fp = fopen("input.txt","r");
char str[80] ;
struct abc{
int num;
char name[20];
int dollar;
};
int i = 0;
while(fgets(str,79,fp)!=NULL){
struct abc a[i] ;
sscanf(str,"%d %[^$]s$%d\n",&a[i].num,a[i].name,&a[i].dollar);
cout <<i+1 <<") Number : "<<a[i].num<<" Name : "<< a[i].name <<" Dollar : "<< a[i].dollar << endl ;
i++;
}
return 0 ;
}
/* These didn't work too.
sscanf(str,"%d %[^$]s %d\n",&a[i].num,a[i].name,&a[i].dollar);
sscanf(str,"%d %[^$]s%d\n",&a[i].num,a[i].name,&a[i].dollar);
sscanf(str,"%d %s$%d\n",&a[i].num,a[i].name,&a[i].dollar);
*/
There's 1 more problem: the first part of string is an int that starts with 0, but the zero is not being accepted in the int. How to do it?
This is working as I want now but still after parasing the string into an int I am not getting the zeroes:
#include<cstdlib>
#include<iostream>
#include<cstring>
using namespace std ;
int main(){
FILE *fp;
fp = fopen("input.txt","r");
char str[80] ;
char temp[80] ;
struct abc{
int num;
char name[20];
int dollar;
};
int i = 0;
int j = 0 ;
while(fgets(str,79,fp)!=NULL){
i = 0;
j = 0 ;
struct abc a[i] ;
char* ptr = 0; // this is used as a helper variable to strtok
ptr = strtok(str, " $\n"); // we specify the delimiters here
while (ptr != NULL)
{
if (j == 0){
strcpy(temp, ptr);
a[i].num = atoi(temp);
}
if (j == 1)
strcpy(a[i].name, ptr);
if (j == 2){
strcpy(temp, ptr);
a[i].dollar = atoi(temp);
}
ptr = strtok(NULL, " $\n");
j++;
}
cout <<i+1 <<") Number : "<<a[i].num<<" Name : "<< a[i].name <<" Dollar : "<< a[i].dollar << endl ;
i++;
}
return 0 ;
}
/* These didn't work either.
sscanf(str,"%d %[^$]s %d\n",&a[i].num,a[i].name,&a[i].dollar);
sscanf(str,"%d %[^$]s%d\n",&a[i].num,a[i].name,&a[i].dollar);
sscanf(str,"%d %s$%d\n",&a[i].num,a[i].name,&a[i].dollar);
*/
Based on the C++ tag, I'd do things a little differently. First I'd overload the stream extractor operator for your abc type:
std::istream &operator>>(std::istream &is, abc &a) {
is >> a.num;
std::getline(is, a.name, '$');
return is >> a.dollar;
}
Then you can use that to read in a file of records, such as:
abc temp;
std::vector<abc> a;
std::ifstream in("input.txt");
while (in >> temp)
a.push_back(temp);
Or, you can use an istream_iterator to initialize a vector directly from the stream:
std::vector<abc> a((std::istream_iterator<abc>(in)),
std::istream_iterator<abc>());
The easiest way to keep the leading zeros on the first number is probably to change it from an int to a std::string.
Use strtok:
Here is a simple code (C only) that prints your strings separately (I recommended a similar solution in another post).
#include <stdio.h>
#include <string.h> // for strcpy and strtok
#include <stdlib.h> // for atoi
int main()
{
char input [25] = "0065445 APPLE$4056"; // input string
// storage for the separate parts of the string
char line[10];
char fruit[10];
char number[10];
char* ptr = 0; // this is used as a helper variable to strtok
ptr = strtok(input, " $\n"); // we specify the delimiters here
int i = 0;
// I'm using i here as a control variable so that during each iteration different part
// of the string is saved
while (ptr != NULL)
{
if (i == 0)
strcpy(line, ptr);
if (i == 1)
strcpy(fruit, ptr);
if (i == 2)
strcpy(number, ptr);
ptr = strtok(NULL, " $\n");
i++;
}
printf("%s %s %s\n", line, fruit, number);
return 0;
}
Some sample output:
$ ./a.out
0065445 APPLE 4056
Is this what you need?
the 0's will not show up when you print the integer a[i].num.
You could make a[i].num a string (char[]) or an integer array. to make the 0's show up. you can parse it as an integer (via atoi(str)), if you need it to be used otherwsie.
#include <iostream>
#include <fstream>
#include <sstream>
struct abc{ int num; std::string name; int dollar; };
int main(int argc, char* argv[]) {
std::ifstream file("input");
abc st1;
std::string l;
while (file >> st1.num >> l) {
if (size_t p = l.find_first_of('$')) {
st1.name = l.substr(0, p);
std::istringstream(l.substr(p+1)) >> st1.dollar;
std::cout << st1.num << " : "
<< st1.name << " : " << st1.dollar << std::endl;
}
}
return 0;
}