How can i include a space (' ') in the resulting concatenated string? - string

The question assigned to me says that when the output of the concatenated string is given, it must have a space ' ' between the 1st and the 2nd string, also, use of in-built function "strcat()" is prohibited. For Example String1=Hello, String2=World, ConcatenatedString=Hello(space)World. I need an assistance. Thank you.
void strconcat(char s1[15], char s2[15])
{
int i;
printf("ENTER A STRING : ");
gets(s1);
printf("ENTER A STRING : ");
gets(s2);
while (s1[i] != '\0')
{
i++;
}
for (int j = 0; s2[j] != '\0'; j++, i++)
{
s1[i] = s2[j];
}
s1[i] = '\0';
puts(s1);
}

If you are allowed to use the in-built c function, size_t strlen(const char *str) then you can save the first while loop.
void strconcat(char s1[15], char s2[15])
{
int i = 0; // You have not initialized this in your code.
printf("ENTER A STRING : ");
gets(s1);
printf("ENTER A STRING : ");
gets(s2);
i = strlen(s1); // If the use of in-built strlen is not allowed then just use the below two lines
s1[i] = ' '; // Here i is at the position of '\0' character in s1 array.
i++;
for (int j = 0; s2[j] != '\0'; j++, i++)
{
s1[i] = s2[j];
}
s1[i] = '\0';
puts(s1);
}

Related

Longest length of valid parenthesis problem

I got stuck on this problem of finding the length of the longest valid parenthesis substring which either contains '(' or ')' . Actually there are many methods to solve this problem but i tried to go with finding the longest common substring (LCS) of the two strings..
I am getting the runtime error....
Line 1061: Char 9: runtime error: addition of unsigned offset to 0x7ffd2d443260 overflowed to 0x7ffd2d44325f (basic_string.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/basic_string.h:1070:9
Please check what is wrong in this....
class Solution {
public:
int LCS(string s1,string s2)
{
int m = s1.length();
int n = s2.length();
int dp[m+1][n+1];
memset(dp,0,sizeof(dp));
for(int i=0;i<=m;i++)
{
for(int j=0;j<=n;j++)
dp[i][j] = 0;
}
int res = 0;
for(int i=0;i<=m;i++)
{
for(int j=0;j<=n;j++)
{
if(i==j)
dp[i][j] = 0;
else if(s1[i-1]==s2[j-1]){
dp[i][j] = 1 + dp[i-1][j-1];
res = max(res,dp[i][j]);
}
else
dp[i][j] = 0;
}
}
return res;
}
int longestValidParentheses(string s) {
// here we can find the longest LCS..
if(s.length()==0 || s.length()==1)
return 0;
string str = "";
for(int i=s.length()-1;i>=0;i--)
{
if(s[i]==')')
str += '(';
else if(s[i]=='(')
str += ')';
}
int res = LCS(s,str);
return res;
}
};

Why can‘t I read the input text file?

I try to read the name of a file using scanf but failed.
I am very bad at pointers and could not find the problem.
Is there a problem with the pointer to the array of string?
Here is my code:
int* Read_file(char* str[])
{
FILE* fp = fopen(str[1], "r");
if(fp == NULL)
{
printf("File cannot open\n");
return NULL;
}
int rows = 0;
while(!feof(fp))
{
if(fgetc(fp) == '\n')
{
rows ++;
}
}
rows ++;
int* keys = (int*)malloc(3 * rows * sizeof(int));
fseek(fp, 0L, 0);
while(!feof(fp))
{
for(int i = 0;i < rows;i ++)
{
for(int j = 0;j < 3;j ++)
{
fscanf(fp,"%d", &keys[(3 * i) + j]);
}
}
}
fclose(fp);
return keys;
}
int main()
{
char* str[20];
printf("Build_tree ");
scanf("%s",&str);
int* keys = Read_file(str);
return 0;
}
Okay, so the thing is:
You need a char array to store a string(file-name). So you should use a char array. Instead, you were using an array of char pointers.
An array is actually a series of memory blocks. The name of the array represents a pointer to the first element of the array(in this case the first char variable).
While reading a string, scanf needs a location to store it. So you need to give it the address of the first char variable of your char array, which is available in your char array itself. So you have to pass str only to scanf. In the case of normal int,float, and such fundamental data types, their names represent memory blocks and not pointers to memory blocks, and hence you had to use a &.
Then for fopen, fopen expects a char*(which points to the first character of the char array stoing the filename) and you have to provide it with a char* . So you should pass str.
I think your code should go like
int* Read_file(char str[])
{
FILE* fp = fopen(str, "r");
if(fp == NULL)
{
printf("File cannot open\n");
return NULL;
}
int rows = 0;
while(!feof(fp))
{
if(fgetc(fp) == '\n')
{
rows ++;
}
}
rows ++;
int* keys = (int*)malloc(3 * rows * sizeof(int));
fseek(fp, 0L, 0);
while(!feof(fp))
{
for(int i = 0;i < rows;i ++)
{
for(int j = 0;j < 3;j ++)
{
fscanf(fp,"%d", &keys[(3 * i) + j]);
}
}
}
fclose(fp);
return keys;
}
int main()
{
char str[20];
printf("Build_tree ");
scanf("%s",str);
int* keys = Read_file(str);
//Whatever you want to do with the keys
return 0;
}
Comment for any queries.

PSET5 Speller Huge Number of Misspelled Words

I have been running the solution but is getting a high number of misspelled words.
WORDS MISSPELLED: 15904 as compared to staff's WORDS MISSPELLED: 955
Other than that, the word count is accurate and the runtime is alright.
I suspect the problem might come from the check / load function but I am not sure what caused it.
Some other code implemented a "to lowercase" in the check function, but I thought the (strcasecmp) would have done the job of comparing between strings, disregarding the case.
Check Function
bool check(const char *word)
{
int hashInt = hash(word);
if (table[hashInt] == NULL)
{
return 1;
}
node *cursor = table[hashInt];
while (cursor != NULL)
{
int i = strcasecmp(cursor -> word, word);
if (i == 0)
{
return 0;
break;
}
cursor = cursor -> next;
}
return false;
}
Load Function
bool load(const char *dictionary)
{
FILE *file = fopen(dictionary, "r");
if (file == NULL)
{
printf("error opening file");
return 1;
}
char word [LENGTH + 1];
while (fscanf(file, "%s\n", word) != EOF)
{
int hashInt = hash(word);
node *n = malloc(sizeof(node));
if (n == NULL)
{
unload();
return 1;
}
if (table[hashInt] == NULL)
{
table[hashInt] = n;
}
else
{
n -> next = table[hashInt];
table[hashInt] = n;
}
strcpy(n -> word, word);
wordLoaded++;
}
fclose(file);
return true;
}
Hash Function
unsigned int hash(const char *word)
{
unsigned int hash = 0;
for (int i = 0, n = strlen(word); i < n; i++)
hash = (hash << 2) ^ word[i];
return hash % N;
return 0;
}
From the spec:
dictionary is assumed to be a file containing a list of lowercase
words
and
Your implementation of check must be case-insensitive.
This int i = strcasecmp(cursor -> word, word); looks like it would fulfill the requirement as long as this int hashInt = hash(word); was also case insensitive. Alas, it is not; hash("A") and hash("a") will return different values.

Merge multiple input strings to sort alphabetically

Help! Here I have a program, that sorts input strings alphabetically. The problem is that it sorts the entered strings seperately, but I need them merged and sorted together. What am i doing wrong?
int main (void)
{
char repeat;
do{
char string[128], string1[128], temp;
int n, i, j;
cout<<"\nEnter symbols: "<<endl;
gets(string);
n = strlen(string);
for (i=0; i<n-1; i++)
{
for (j=i+1; j<n; j++)
{
int s = tolower(string[i]) - tolower(string[j]);
if ( s == 0 )
{
s = string[i] - string[j];
}
if (s > 0)
{
temp = string[i];
string[i] = string[j];
string[j] = temp;
}
}
}
cout<<"\nSorted alphabetically: "<<endl;
printf("\n%s", string);
printf("\n");
cout<<"\nEnter more symbols: "<<endl;
gets(string1);
n = strlen(string1);
for (i=0; i<n-1; i++)
{
for (j=i+1; j<n; j++)
{
int s = tolower(string1[i]) - tolower(string1[j]);
if ( s == 0 )
{
s = string1[i] - string1[j];
}
if (s > 0)
{
temp = string1[i];
string1[i] = string1[j];
string1[j] = temp;
}
}
}
cout<<"\nSorted alphabetically: "<<endl;
the function below merges the strings, when they both have been already sorted
strcat(string, string1);
printf(\n%s", string);
printf("\n");
cout << "To repeat press j" << endl;
cin >> repeat;
}
while ( repeat == 'j' );
system("Pause");
return 0;
}
The easiest way is to merge the strings into a new one.
int main (void)
{
char repeat;
do{
char string[128], string1[128],string2[256], temp;
int n, i, j;
cout<<"\nEnter symbols: "<<endl;
gets(string);
cout<<"\nEnter more symbols: "<<endl;
gets(string1);
strcpy (string2,string);
strcat (string2,string1);
// rest of your code here. You only need to sort string2

Memory allocation and deallocation

Here is the entire program, please help me, I've tried everything to find out what exactly is going with the memory. The problem is everything runs perfectly, but there are some extra characters printed with output.
Here is the .h file:
class MyString
{
public:
MyString();
MyString(const char *message);
MyString(const MyString &source);
~MyString();
const void Print() const;
const int Length() const;
MyString& operator()(const int index, const char b);
char& operator()(const int i);
MyString& operator=(const MyString& rhs);
bool operator==(const MyString& other) const;
bool operator!=(const MyString& other) const;
const MyString operator+(const MyString& rhs) const;
MyString& operator+=(const MyString& rhs);
friend ostream& operator<<(ostream& output, const MyString& rhs);
const int Find(const MyString& other);
MyString Substring(int start, int length);
private:
char *String;
int Size;
};
istream& operator>>(istream& input, MyString& rhs);
The .cpp file:
MyString::MyString()
{
char temp[] = "Hello World";
int counter(0);
while(temp[counter] != '\0')
{
counter++;
}
Size = counter;
String = new char [Size];
for(int i=0; i < Size; i++)
String[i] = temp[i];
}
//alternate constructor that allows for setting of the inital value of the string
MyString::MyString(const char *message)
{
int counter(0);
while(message[counter] != '\0')
{
counter++;
}
Size = counter;
String = new char [Size];
for(int i=0; i < Size; i++)
String[i] = message[i];
}
//copy constructor
MyString::MyString(const MyString &source)
{
int counter(0);
while(source.String[counter] != '\0')
{
counter++;
}
Size = counter+1;
String = new char[Size];
for(int i = 0; i <= Size; i++)
String[i] = source.String[i];
}
//Deconstructor
MyString::~MyString()
{
delete [] String;
}
//Length() method that reports the length of the string
const int MyString::Length() const
{
int counter(0);
while(String[counter] != '\0')
{
counter ++;
}
return (counter);
}
/*Parenthesis operator should be overloaded to replace the Set and Get functions of your previous assignment. Note that both instances should issue exit(1) upon violation of the string array bounaries.
*/
MyString& MyString::operator()(const int index, const char b)
{
if(String[index] == '\0')
{
exit(1);
}
else
{
String[index] = b;
}
}
char& MyString::operator()(const int i)
{
if(String[i] == '\0')
{
exit(1);
}
else
{
return String[i];
}
}
/*Assignment operator (=) which will copy the source string into the destination string. Note that size of the destination needs to be adjusted to be the same as the source.
*/
MyString& MyString::operator=(const MyString& rhs)
{
if(this != &rhs)
{
delete [] String;
String = new char[rhs.Size];
Size = rhs.Size;
for(int i = 0; i < rhs.Size+1 ; i++)
{
String[i] = rhs.String[i];
}
}
return *this;
}
/*Logical comparison operator (==) that returns true iff the two strings are identical in size and contents.
*/
bool MyString::operator==(const MyString& other)const
{
if(other.Size == this->Size) {
for(int i = 0; i < this->Size+1; i++)
{
if(&other == this)
return true;
}
}
else
return false;
}
//Negated logical comparison operator (!=) that returns boolean negation of 2
bool MyString::operator!=(const MyString& other) const
{
return !(*this == other);
}
//Addition operator (+) that concatenates two strings
const MyString MyString::operator+(const MyString& rhs) const
{
char* tmp = new char[Size + rhs.Size +1];
for(int i = 0; i < Size; i++)
{
tmp[i] = String[i];
}
for(int i = 0; i < rhs.Size+1; i++) {
tmp[i+Size] = rhs.String[i];
}
MyString result;
delete [] result.String;
result.String = tmp;
result.Size = Size+rhs.Size;
return result;
}
/*Addition/Assigment operator (+=) used in the following fashion: String1 += String2 to operate as String1 = String1 + String2
*/
MyString& MyString::operator+=(const MyString& rhs)
{
char* tmp = new char[Size + rhs.Size + 1];
for(int i = 0; i < Size; i++) {
tmp[i] = String[i];
}
for(int i = 0; i < rhs.Size+1; i++)
{
tmp[i+Size] = rhs.String[i];
}
delete [] String;
String = tmp;
Size += rhs.Size;
return *this;
}
istream& operator>>(istream& input, MyString& rhs)
{
char* t;
int size(256);
t = new char[size];
input.getline(t,size);
rhs = MyString(t);
delete [] t;
return input;
}
ostream& operator<<(ostream& output, const MyString& rhs)
{
if(rhs.String != '\0')
{
output << rhs.String;
}
else
{
output<<"No String to output\n";
}
return output;
}
/*MyString::Find that finds a string in a larger string and returns the starting location of the substring. Note that your string location starts from 0 and ends at length -1. If the string is not found, a value of -1 will be returned
*/
const int MyString::Find(const MyString& other)
{
int nfound = -1;
if(other.Size > Size)
{
return nfound;
}
int i = 0, j = 0;
for(i = 0; i < Size; i++) {
for(j = 0; j < other.Size; j++) {
if( ((i+j) >= Size) || (String[i+j] != other.String[j]) )
{
break;
}
}
if(j == other.Size)
{
return i;
}
}
return nfound;
}
/*MyString::Substring(start, length). This method returns a substring of the original string that contains the same characters as the original string starting at location start and is as long as length.
*/
MyString MyString::Substring(int start, int length)
{
char* leo = new char[length+1];
for(int i = start; i < start + length+1; ++i)
{
leo[i-start] = String[i];
}
MyString sub;
delete [] sub.String; sub.String = leo; sub.Size = Size;
return sub;
}
//Print() method that prints the string
const void MyString::Print() const
{
for(int i=0; i < Size; i++)
{
cout<<String[i];
}
cout<<endl;
}
The main.cpp file:
int main (int argc, char **argv)
{
MyString String1;
const MyString ConstString("Target string"); //Test of alternate constructor
MyString SearchString; //Test of default constructor that should set "Hello World".
MyString TargetString (String1); //Test of copy constructor
cout << "Please enter two strings. ";
cout << "Each string needs to be shorter than 256 characters or terminated by /\n." << endl;
cout << "The first string will be searched to see whether it contains exactly the second string. " << endl;
cin >> SearchString >> TargetString; // Test of cascaded string-extraction operator
if(SearchString.Find(TargetString) == -1) {
cout << TargetString << " is not in " << SearchString << endl;
}
else {
cout << TargetString << " is in " << SearchString << endl;
cout << "Details of the hit: " << endl;
cout << "Starting position of the hit: " << SearchString.Find(TargetString) << endl;
cout << "The matching substring is: " << SearchString.Substring(SearchString.Find(TargetString), TargetString.Length()-1)<<"\n";
}
return 0;
}
Running the program you get this:
Please enter two strings. Each string needs to be shorter than 256 characters or terminated by /
.
The first string will be searched to see whether it contains exactly the second string.
firstly
real
realt World is not in firstly
Please Help!!
try adding a '\0' at the end of your strings in your MyString::MyString(const char *message) constructor
#Sam's answer is correct. I'm going to add on to it to help you learn what's happening.
C and C++ strings are really character arrays that follow a convention that the string is terminated with \0, sometimes called NUL (not null), which is a character where all bits are 0.
Your code gets the first part right in that it creates an array of characters. However, you do not apply the convention that the string must be NUL terminated.
You then pass a string that does not follow the NUL termination convention to cout, which does follow that convention. In other words, it runs through the string, printing each character to stdout, until it happens across the character \0 in memory. It's actually fairly lucky that it terminates. If there were not a \0 in the character array it is outputing, it would just keep on going until reaching a memory address that does not belong to your program and failing with a segmentation fault.

Resources