2

I have to build a String class using string.h (you will understand when you see the code). Please forgive my poor English. I don't know where the problem is. It just crashes without any error messages.

(String.h)

#ifndef _STRING_H
#define _STRING_H

class String{
public:
    char* s1;
    char* s2;
    char* stemp;


    //The Constructors
    String();
    String(char* so);
    String(char* so, char* st);

    //Member Functions
    int slength(char* s1);  //Calculate the length of Sting
    void scopy(char* so,const char* st);    // copy string value to another String


};



#endif // _STRING_H

(String.cpp)

#include <string.h>
#include "String.h"

//The Constructors
String::String(){}

String::String(char* so){
    s1 = so;
}
String::String(char* so, char* st){
    s1 = so;
    s2 = st;
}


//Member Functions

int String::slength(char* so){
    return strlen(so);
}

void String::scopy(char* so,const char* st){

    strcpy(so,st);
}

(main.cpp)

#include <iostream>
#include "String.h"


using namespace std;

int main()
{

    String str("Hello","World");


    cout<<"The First  String is : "<<str.s1<<endl;
    cout<<"The Second String is : "<<str.s2<<endl;
    cout<<"-------------------------------------"<<endl;

    cout<<"The First String contains "<<str.slength(str.s1)<<" Letters"<<endl;
    cout<<"The Second String contains "<<str.slength(str.s2)<<" Letters"<<endl;

    cout<<"-------------------------------------"<<endl;

    cout<<"Copying The Second String in the First String . . ."<<endl;
    str.scopy(str.s1,str.s2);
    cout<<"The First  String is : "<<str.s1<<endl;
    cout<<"The Second String is : "<<str.s2<<endl;


    return 0;
}
Jim Simson
  • 2,774
  • 3
  • 22
  • 30
Mexyzer
  • 21
  • 6
  • 1
    Did you try debugging your code? Update: What is it today, with people trying to write to string literals? String literals in C++ are (to be considered) read-only. – Algirdas Preidžius Dec 04 '15 at 14:13
  • yes : Program received signal SIGSEGV, Segmentation fault. In strcat () (C:\Windows\system32\msvcrt.dll) i didn't use strcar(); ?!? – Mexyzer Dec 04 '15 at 14:15
  • Did you try using `where` command if you use GDB? – MikeCAT Dec 04 '15 at 14:17
  • @MohamedFarhat no you didn't. Put a breakpoint on a first line of `main` function, and step through your code line-by-line. Total time elapsed to find a bug - 30 seconds. – Algirdas Preidžius Dec 04 '15 at 14:18
  • i'm using (code::blocks 13.12) . – Mexyzer Dec 04 '15 at 14:19
  • oh , i did that the problem in the line : str.scopy(str.s1,str.s2); – Mexyzer Dec 04 '15 at 14:22
  • 1
    There are lots of errors with your code as presented. I would suggest you look at how other people have implemented a custom string class. You can check this out for starters: http://stackoverflow.com/questions/2843421/custom-string-class-c – NathanOliver Dec 04 '15 at 14:27
  • OT: Your include guard is illegal. https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier – Baum mit Augen Dec 04 '15 at 14:31
  • i just looked into that before i submit this problem . I'm just trying to solve the strcpy(); probelm . and i'm making a defferent type of custom string classes . – Mexyzer Dec 04 '15 at 14:35
  • There is nothing wrong with my include guard , i used String with a capital "S" as a class name and a file name and there's nothing wrong with that – Mexyzer Dec 04 '15 at 14:47
  • @Mexyzer - names that begin with an underscore followed by a capital letter (as well as names that contain two consecutive underscores) are reserved to the implementation. You should not use them. That's the problem with `_STRING_H_`. – Pete Becker Dec 04 '15 at 15:42

2 Answers2

3

A string literal is assigned to str.s1, and is is passed as the first argument of strcpy in String::scopy(). It is very bad because modifying string literal isn't allowed.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • and what should i do ? – Mexyzer Dec 04 '15 at 14:19
  • 1
    @Mexyzer Your string class should not copy the pointers, but rather allocate memory and use `strcpy` to keep an own copy of the strings. – MicroVirus Dec 04 '15 at 14:28
  • sorry i can't understand what are you saying . maybe because of my english . – Mexyzer Dec 04 '15 at 14:37
  • can you give me an example of what you are saying – Mexyzer Dec 04 '15 at 14:38
  • 1
    @Mexyzer: For example, replace `s1 = so;` with `s1 = strdup(so);` (`strdup` allocates and populates a new C-style string from an existing C-style string). But you'd need to add a destructor to your class to `free` `s1`. – ShadowRanger Dec 04 '15 at 14:46
  • @Mexyzer: Or use `strlen`, C++ `new` to allocate an array of `char`, and `strcpy` to fill it. But regardless, you'd need to add a destructor to your class to `free`/`delete[]` `s1` (or make `s1`, `s2`, `stemp` etc. be `std::unique_ptr`, customizing the deallocator if it's not the default `delete`). – ShadowRanger Dec 04 '15 at 14:53
  • oh man _ i'm just a beginner , i don't know that much .. i can't understand you talking in scientific words – Mexyzer Dec 04 '15 at 15:03
0

I just Solved the Problem

(String.h)

#ifndef STRING_H
#define STRING_H

class String{
    public:
        //Data Members
        char* s1;
        int len ;

        //The Constructors
        String();
        String(char* so);

        //Member Functions
        int slength(String &s1);  //Calculate the length of Sting
        void scopy(String &so,String &st);    // copy string value to another String
        int scompare(String &so, String &st); // compare two string and returns which one is bigger
        void scombine(String &so, String &st);    // combine two strings into one string
        //The Destructor
        ~String();

};



#endif // STRING_H

(String.cpp)

#include <string.h>
#include "String.h"

//The Constructors
String::String(){
    len = 0;
    s1 = new char[len + 1];
}

String::String(char* so){
    len = strlen(so);
    s1 =  new char[len + 1];
    strcpy(s1, so);

}


//Member Functions

int String::slength(String &so){
    return strlen(so.s1);
}

void String::scopy(String &so,String &st){

    strcpy(so.s1,st.s1);
}

int String::scompare(String &so, String &st){
    return strcmp(so.s1,st.s1);

}


void String::scombine(String &so, String &st){
    len = so.len + st.len;
    delete s1;
    s1 = new char[len + 1];
    strcpy(s1,so.s1);
    strcat(s1,st.s1);

}


//The Destructor
String::~String(){}

(main.cpp)

#include <iostream>
#include "String.h"


using namespace std;

int main()
{

String str1("Hello");
String str2("World");
String str;


cout<<endl<<"The First  String is : "<<str1.s1<<endl;
cout<<"The Second String is : "<<str2.s1<<endl;
cout<<endl<<"-------------------------------------"<<endl;

cout<<endl<<"The First  String contains "<<str.slength(str1)<<" Letters"<<endl;
cout<<"The Second String contains "<<str.slength(str2)<<" Letters"<<endl;

cout<<endl<<"-------------------------------------"<<endl;

cout<<endl<<"After Comparing the Two Strings we Find out That"<<endl;
switch(str.scompare(str1,str2)){
    case 1:
        cout<<"The First String is Bigger than the Second String";
        break;
    case 0:
        cout<<"The two Strings are the equal";
        break;
    default:
        cout<<"The Second String is Bigger than the First String";
}

cout<<endl<<endl<<"-------------------------------------"<<endl;

cout<<endl<<"After Combining The two Strings"<<endl;
str.scombine(str1,str2);
cout<<str.s1<<endl;


cout<<endl<<"-------------------------------------"<<endl;

cout<<endl<<"After copying The Second String in the First String . . ."<<endl;
str.scopy(str1,str2);
cout<<"The First  String is : "<<str1.s1<<endl;
cout<<"The Second String is : "<<str2.s1<<endl;


    return 0;
}
Mexyzer
  • 21
  • 6