why my cpp code can't run?(about char*[]) - c++

this is my code
the error is Segmentation fault,and i can't understand why
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
char* szword[100];
int i = 0;
do
{
cin >> szword[i];
cout << szword[i];
i++;
}while(strcmp(szword[i - 1], "done"));
cout << i + 1;
return 0;
}

For starters neither declaration from headers <cstdio> and <string> is used in your program. So you should remove these directives
#include <cstdio>
#include <string>
You declared an initialized array with the element type char *. Thus this statement
cin >> szword[i];
invokes undefined behavior because the pointer szword[i] has indeterminate value.
Moreover this call even if the argument of the operator will be correct
cin >> szword[i];
can fail. You should check whether it was successful. And I think there is no great sense to output the string "done".
Also in this statement
cout << i + 1;
you are outputting a value that is greater than the number of inputted strings.
If to use character arrays then your program could look the following way
#include <iostream>
#include <cstring>
int main()
{
const size_t N = 100;
char szword[N][N];
size_t i = 0;
while ( std::cin.getline( szword[i], sizeof( szword[i] ) ) &&
std::strcmp( szword[i], "done" ) != 0 )
{
std::cout << szword[i++] << '\n';
}
std::cout << i << '\n';
return 0;
}
The program output might look like
Hello
World
2

This below code works fine, if you want to use char *, for C++ string you can use the C++ version
C Version:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
char *tmp;
int i = 0;
do
{
cin >> tmp;
cout << tmp;
i++;
}while(strcmp(tmp, "done"));
cout << i + 1;
return 0;
}
C++ Version:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
string tmp;
int i = 0;
do
{
cin >> tmp;
cout << tmp;
i++;
}while(tmp != "done"));
cout << i + 1;
return 0;
}

Related

How can I replace multiple characters with just one (C++)?

We have a char. We need to replace all ab characters from our char with the letter c.
Example we have :
abracadabra
the output will be :
cracadcra
I tried to use replace() function from C++, but no success.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
string test;
cin>>test;
for(int i=0;i<(strlen(test)-1);i++)
{
if((test[i]=='a')&&(test[i+1]=='b')){
test.replace( test[i], 'c' );
test.replace( test[i+1] , ' ' );
}
}
cout << test << endl;
return 0;
}enter code here
You can use C++11 regex:
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string str = "abracadabra";
std::regex r("ab");
std::cout << std::regex_replace(str, r, "c") << "\n"; // cracadcra
}
Problem:
That is not the syntax of std::string::replace.
Solution:
As is mentioned here the syntax is std::string::replace(size_t pos, size_t len, const string& str). Do test.replace(i, 2, "c" ) instead of test.replace(test[i],'c').
Or use regular expressions as dtell pointed.
Adittional information:
using namespace std; is considered a bad practice (More info here).
You should use std::string::size instead of strlen when you're working with std::string.
To work with std::string you should use #include <string> instead of #include <cstring>.
Full code:
#include <iostream>
int main()
{
std::string test;
std::cin >> test;
for(unsigned int i = 0; i < test.size() - 1; i++)
{
if((test[i]=='a') && (test[i+1]=='b'))
{
test.replace(i, 2, "c" );
}
}
std::cout << test << std::endl;
return 0;
}
The simplest thing you can do by using the standard library is first to find ab and then replace it. The example code I wrote is finding string ab unless there is None in the string and replacing it with c.
#include <iostream>
#include <string>
int main()
{
std::string s = "abracadabra";
int pos = -1;
while ((pos = s.find("ab")) != -1)//finding the position of ab
s.replace(pos, sizeof("ab") - 1, "c");//replace ab with c
std::cout << s << std::endl;
return 0;
}
//OUTPUT
cracadcra

Error while performing string copy operation in C++

Please explain why is this giving an error but the other on is running fine
The following code gives the error:
#include <iostream>
#include <string>
#include <conio.h>
#include <math.h>
#include <iomanip>
#include <string.h>
using namespace std;
int main()
{
string s1,s2;
int i;
cout << "Enter the string to copy into another string : ";
getline(cin,s1);
for(i=0; s1[i]!='\0'; ++i)
{
s2[i]=s1[i];
}
s2[i]='\0';
cout<<"\n\nCopied String S2 is : "<<s2;
return 0;
}
Error looks like this
But this works perfectly fine
#include <iostream>
#include <string>
#include <conio.h>
#include <math.h>
#include <iomanip>
#include <string.h>
using namespace std;
int main()
{
char s1[100], s2[100], i;
cout << "Enter the string to copy into another string : ";
cin>>s1;
for(i=0; s1[i]!='\0'; ++i)
{
s2[i]=s1[i];
}
s2[i]='\0';
cout<<"\n\nCopied String S2 is : "<<s2;
return 0;
}
In your case, s2 is initialized to an empty string with a length of 0, so you can't write past the bounds. If you want to, you must first resize it:
s2.resize(s1.length());
for(i=0; s1[i]!='\0'; ++i)
{
s2[i]=s1[i];
}
Also, c++ std::string does not need a terminating nullbyte, unlike C strings.

Sort a Substring in Descending order using Vector, however getting segmentation fault

I want to sort the string from N to M where N indicates the starting index and M indicates the ending index.
However, my code is getting failed with segmentation fault.
Here is my code:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
string s;
int M=0,N=0;
cout<<"Enter String"<<endl;
getline(cin,s);
vector<char> data(s.begin(), s.end());
cout<<"Enter start_index and end_index for sorting";
cin>>N>>M; //Passed externally as N=start_index, M=end_index
std::sort(data.begin()+N, data.begin()+M, std::greater<char>());
for (std::vector<char>::const_iterator i = data.begin(); i != data.end(); ++i)
std::cout << *i << ' ';
return 0;
}
This example does work fine for me:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
string s = "ABCDEFG";
int N = 1;
int M = 5;
vector<char> data(s.begin(), s.end());
std::sort(data.begin() + N, data.begin() + M, std::greater<char>());
for (auto& character : data)
std::cout << character << ' ';
return 0;
}
http://coliru.stacked-crooked.com/a/ee7c5f05afe85115
I suspect you get an empty string with cin, and therefore your data.begin() is invalid.
Be cautious with user entered data. Always do proper checking for input that may break your code.
Additonally your templated greater is the comparing function for the wrong type.
The answer to the above question is from the guidance of Trevir.
In order to avoid the segmentation fault, check the size of the input
string and then apply operations on it.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
string s;
int M,N;
cout<<"Enter String"<<endl;
getline(cin,s);
if ( s.size() == 0 )
{
std::cout << "Empty Input" << std::endl;
return 0;
}
vector<char> data(s.begin(), s.end());
cout<<"Enter start_index and end_index for sorting";
cin>>N>>M; //Passed externally as N=start_index, M=end_index
std::sort(data.begin()+N, data.begin()+M, std::greater<char>());
for (std::vector<char>::const_iterator i = data.begin(); i != data.end(); ++i)
std::cout << *i;
return 0;
}

Why do I get an Segmentation fault error

My code works fine on codeblocks compiler on my computer but when I upload it to an online editor I get an Segmentation fault error and I don't know why.
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <fstream>
using namespace std;
int main(int argc, char *argv[]) {
ifstream stream(argv[1]);
char line[1000];
int x,last=-1;
while (stream>>line)
{
x = atoi(strtok(line,","));
cout<<x;
last=x;
while(x=atoi(strtok(NULL,",")))
{
if(x!=last)
{
cout<<","<<x;
last=x;
}
}
cout<<endl;
}
return 0;
}
You are given a sorted list of numbers with duplicates. Print out the sorted list with duplicates removed.
And this is the input
6,7,8,9,9,10,11,12,13,14,15
11,12,13,14,15,16,17,18,19,20
2,2,2,2,2
10,11,12,13,14,15,16,16,17
13,14,14,15,16,17,17,17,18
15,16,17,17,18,18,18,18,19,19,20
2,3,4,5,5
13,14,15,16,17
10,11,12,13,14,15,15,15,15,16,16,16
12,13,14,15,16,17,17,18
5,6,7,8,9,10,11
14,14,14,15,15,16,17,17,18,19,19,20,21,22
13,14,15,16,16,17,17,18
15,16,17,18,19,20,21,21,21,21,22,22
6,6,6,7,8,9,10,11,11,11,12,12,13
12,12,13,14,15,15,16,17,17,18,19,19,20,21
8,9,9,9,10,10,11,12,13,13,14,15
12,13,14,15,16,17,18
1,1,1,2,2,3,3,4,4
1,2,3,4
Since you're asking us to guess, let's start at the top ....
The code doesn't check that argv[1] is valid. If not, then you just dereferenced a null-pointer, and that caused your segmentation fault.
Does your "online editor" pass parameters? I suggest checking argc > 1.
Next, your code looks like it will pass a null pointer to atoi at the end of every line. That's another segmentation fault.
You are calling atoi with the result of strtok.
If strtok doesn't find anything it returns a null pointer.
This is the case at the end of the line.
So you are passing a null pointer to atoi which then leads to a crash.
Using your example this should work:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
ifstream stream(argv[1]);
char line[1000];
char* ln;
char* num;
int x;
int last;
while (stream >> line)
{
ln = line;
last = -1;
while (num = strtok(ln, ","))
{
x = atoi(num);
if (x != last)
{
if(last != -1) cout << "," << x;
else cout << x;
last = x;
}
ln = NULL;
}
cout << endl;
}
return 0;
}
EDIT: Another solution with checking for valid paramters and w/o strtok and atoi:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
if (argc < 2) {
cout << "Usage: " << argv[0] << " <file>";
return 1;
}
ifstream stream(argv[1]);
if (!stream.is_open())
{
cout << "Failed to open file \"" << argv[1] << "\"";
return 2;
}
char line[1000];
while (stream >> line)
{
int last = -1;
int x = 0;
for (char* pos = line; pos < line + strlen(line); pos++)
{
if (*pos >= '0' && *pos <= '9')
{
x = (x * 10) + (*pos - '0');
}
else
{
if (last != x)
{
if (last != -1) {
cout << ',';
}
cout << x;
last = x;
}
x = 0;
}
}
cout << endl;
}
return 0;
}

Problems with fstream

I'm writing a vector array to an ofstream file, however certain values aren't getting written, I.E.:
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
int main (){
char * hold = new char [100];
vector<double> fx(2049);
ifstream inputFile;
ofstream myFile;
inputFile.open("data.txt");
myFile.open("test.txt");
for (int c=0; c<2049; c++){
inputFile.getline(hold, 100);
fx[c] = atof(hold);
}
for (int c=0; c<2049; c++){
myFile << fx[c] << "\n";
}
}
Within fx, the second half is all equal to 0. (fx[1024] through fx[2048]==0). Within test.txt however, none of these 0 values are present, on the carriage return is applied. Any thoughts?
Thanks! (New to the formatting of these questions... any tips to make this more understandable would be appreciated.)
Note: I realize this program is rather redundant. The actual program has a great deal more functionality to it, this is just an area that is working incorrectly.
Try this
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstdlib>
#define MAX_FILE_LINES 2048
using namespace std;
//genarate random double number
double fRand()
{
double fMin = 100, fMax = 200;
double f = (double)rand();
return fMin + (f / (fMax - fMin));
}
//init file (if you need to create sample file with list of double numbers, you can use this function)
void fileInit(){
ofstream sourceFile;
sourceFile.open("D:\\source.txt");
if (sourceFile.is_open())
{
for (int i=0; i<MAX_FILE_LINES; i++){
sourceFile << fRand() << endl;
}
}
}
int main (){
string buffer;
vector<double> fx(MAX_FILE_LINES);
ifstream sourceFile;
ofstream destinationFile;
sourceFile.open("D:\\source.txt");
destinationFile.open("D:\\destination.txt");
//reading file lines to vector
int lineCount =0;
if (sourceFile.is_open())
{
while ( sourceFile.good() )
{
getline (sourceFile,buffer);
fx[lineCount] = atof(buffer.c_str());
lineCount++;
if (lineCount == (MAX_FILE_LINES-1)){
break;
}
}
sourceFile.close();
}
//write lines to new file
if (destinationFile.is_open())
{
for (int i=0; i<MAX_FILE_LINES; i++){
destinationFile << fx[i] << endl;
}
}
}
Why screw with handroll buffers for one-offs? You can't save a millionth of what it costs to think about cycles here, there's not enough waste to recoup.
Think about eliminating needless statements and unchecked failures first.
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<float> data;
{
ifstream ids("source.txt",ios_base::in);
int linenr = 0;
for ( string line ; getline(ids,line) ; ) {
++linenr;
decltype(data)::value_type x;
istringstream s(line);
if ( s >> x )
data.push_back(x);
else
cerr << "crap line "<<linenr<<" ignored: " << line << '\n';
}
}
ofstream ods("object.txt");
for ( auto x : data )
ods << x << '\n';
}