Suggest logic with one loop to concatenate two strings without strcat - c++

I have written a program to concatenate two strings without using strcat using two while loops for beginners. Need your suggestion to code it with one loop. Kindly share your logic thanks

char first[1000];
char second[2000];
char result[4000];
void concat(char *first, char *second, char *result){
int str_selector = 0;
int i = 0, result_pos = 0;
char *current_str = first;
while(1){
if(str_selector == 1 && current_str[i] == '\0'){
result[result_pos] = '\0';
break;
}
if(str_selector == 0)
current_str = first;
else
current_str = second;
if(current_str[i] != '\0'){
result[result_pos] = current_str[i];
result_pos++;
i++;
}
else{
i = 0;
str_selector = 1;
}
}
}

Related

Debugging Help required to concatenate two char arrays in third one using function in C++

I just can't figure out why it is not compiling.After spending an hour to it,i decided to get some help from you guys.According to my understandings the first "for" loop will surely copy whole string s1 to s3.I don't know why it crashes.Actually i am naive to programming more to be entitled as "Beginner to C++".
So i don't want to use built in function because i am learning concept of user defined functions.
I have called function in main() as string_cat(s1,s2);
void string_cat(char *s1, char*s2){
char s3[200]; int i = 0, j = 0;
for (i=0; s1[i] != '\0'; i++){
s3[i] = s1[i];
}
while (s3[i] != '\0')
{
i++;
}
while (s2[j] != '\0')
{
s3[i++] = s2[j++];
}
s3[i] = NULL;
cout << s3 << endl;
}
I made your code working with minor changes:
#include<iostream>
using namespace std;
void string_cat(char *s1, char*s2)
{
char s3[200]; int i = 0, j = 0;
for (i=0; s1[i] != '\0'; i++){
s3[i] = s1[i];
}
while (s2[j] != '\0')
{
s3[i++] = s2[j++];
}
s3[i] = '\0';
cout << s3 << endl;
}
int main()
{
char str1[5] = "abcd";
char str2[5] = "efgh";
string_cat(str1, str2);
}
You should write: s3[i] = '\0';
Compile:
$ g++ StringMerge.cpp -o StringMerge.o
Run:
$ ./StringMerge.o
abcdefgh

Split char* at delimiter in freestanding mode c++

I am trying to write my own operating system. I have followed the tutorials on the OSDev Wiki, and I am now working on writing a console mode, with commands. I need to be able to split a char* into a char**, without all the library functionality (hence freestanding). I have tried iterating through until I meet my delimiter etc, but however I do it, I just get garbage stuck on the end of my first result. What am I doing wrong? This is what I have so far:
static char** splitStr (char* string, char delim) {
char returner[VGA_WIDTH][255];
int loc = 0;
int innerLoc = 0;
for (int i = 0; string[i] != 0x00; i++) {
char c = string[i];
if (c != delim) {
returner[loc][innerLoc] = c;
innerLoc++;
} else {
print ("a string was ");
println (returner[loc]);
innerLoc = 0;
loc++;
}
}
print ("the first string was ");
println (returner[0]);
return (char**)returner;
}
I am asking a question about how to write a specific function in C++ freestanding mode.
void split(const char* str, const char d, char** into)
{
if(str != NULL && into != NULL)
{
int n = 0;
int c = 0;
for(int i = 0; str[c] != '\0'; i++,c++)
{
into[n][i] = str[c];
if(str[c] == d)
{
into[n][i] = '\0';
i = -1;
++n;
}
}
}
}
I'm allocating using calloc to get rid of garbage characters.
EDIT: You should allocate the pointers inside the char** before writing to them.
void allocarr(char** pointers, int bytes, int slots)
{
int i = 0;
while(i <= slots)
{
pointers[i] = (char*)calloc(1, bytes);
++i;
}
}
...
char** sa = (char**)malloc(50*sizeof(char*));
allocarr(sa, 512, 50);
split("Hello;World;", ';', sa);
puts(sa[0]);

Member variable does not save value added to it from member from functiion

Hello I have a small problem, I am trying to assign value to some member variable of my class from a member function. Everything seems fine but once my program is returns to EAN::read(...); there are weird characters now in the member variable -->"╠╠╠╠╠╠". Anyone can explain to me what im doing wrong? Thank you.
///My class ////
class EAN
{
char string[13];
char strStyle[18];
char styles[2];
char area[6];
char publisher[8];
char title[8];
bool registered;
public:
///and member functions here//
};
////First member function that is called///
bool EAN::read(std::istream& is, const Prefix& list){
char str[13];
bool keepgoing = false;
do{
cout << "Enter a EAN(0 to quit): ";
is >> str;
if (str == nullptr || strlen(str) < 13){
keepgoing = false;
registered = false;
}
else{
keepgoing = true;
EAN(str, list); ///this is where member variable will be assigned//
registered = true;
std::cout << "this is area" << area << endl;
}
} while (keepgoing == false);
return keepgoing;
}
////////Here is the constructor that assigns the values to member variable//
EAN::EAN(const char* str, const Prefix& list){
int keepgoing = 0, j = 3, i = 0;
string[13] = '\0';
strStyle[18] = '\0';
area[6] = '\0';
publisher[8] = '\0';
title[8] = '\0';
if (isValid(str) == 1 && str[0] == '9' && str[1] == '7'|| str[2] == '8' || str[2] == '9') {
keepgoing = 1;
strcpy(string, str);
if (isRegistered(list) == true){
char _area[6];
int lengthArea = 0;
while (i < 5) {
_area[i] = str[j];
_area[i + 1] = '\0';
if (list.isRegistered(atoi(_area))) {
strcpy(area, _area); **<--- ///assign value to member variable.///**
lengthArea = strlen(area);
i = 6; // exit loop
keepgoing = 1;
}
else
{
i++;
j++;
}
}
.......more coding pretty same as above.
}
All of these values, you're writing off the end of the allocated memory:
string[13] = '\0';
strStyle[18] = '\0';
area[6] = '\0';
publisher[8] = '\0';
title[8] = '\0';
If you want to set the last character to null you do it like this:
char string[13];
string[12] = '\0';
Because zero-indexed;
Hey guys thanks for the help i figure it out if you look carefully guys, I called the constructor inside a member function but i for to return what i make that constructor assigns.
so i was missing *this = EAN(str, list);
Thanks for the help guys.

C++ iostream read with delimiter of MULTIPLE bytes

We know to read from an input stream, we can use the below standard C++ function
istream& getline (char* s, streamsize n, char delim );
However we can only provide delimiter of one byte/char.
How should I do if I wish to use delimiter with multiple bytes?
Is there any neat stuff I can leverage, boost?
Bests,
Lyn
I think you can use cin.get() instead of cin.getline(). Read one character each time and test whether the delimiter occurs.
int main(void){
string str;
int length_of_delimiter = 3;
const char *delimiter = "ABC";
char temp = '0';
bool over = false;
cout<<"Enter the stream"<<endl;
temp = cin.get();
int i = 0;
while(over == false){
for(i = 0; temp == delimiter[i] && i < length_of_delimiter; i++){
str += temp;
temp = cin.get();
}
if(i == length_of_delimiter){
//chop off the delimiter
str.erase(str.end() - length_of_delimiter, str.end());
over = true;
}
else {
str += temp;
temp = cin.get();
}
}
cout<<"The stream we wanted is: "<<str<<endl;
return 0;
}

Strings with whitespace in a list?

I have this function sentanceParse with a string input which returns a list. The input might be something like "Hello my name is Anton. What's your name?" and then the return value would be a list containing "Hello my name is Anton" and "What's your name?". However, this is not what happens. It seems as if the whitespaces in the sentences are treated like a separator and therefore the return is rather "Hello", "my", "name" etc instead of what I expected.
How would you propose I solve this?
As I am not a 100% sure the problem does not lie within my code, I will add that to the post as well:
Main:
list<string> mylist = sentanceParse(textCipher);
list<string>::iterator it;
for(it = mylist.begin(); it != mylist.end(); it++){
textCipher = *it;
cout << textCipher << endl; //This prints out the words separately instead of the entire sentances.
sentanceParse:
list<string> sentanceParse(string strParse){
list<string> strList;
int len = strParse.length();
int pos = 0;
int count = 0;
for(int i = 0; i < len; i++){
if(strParse.at(i) == '.' || strParse.at(i) == '!' || strParse.at(i) == '?'){
if(i < strParse.length() - 1){
while(i < strParse.length() - 1 && (strParse.at(i+1) == '.' || strParse.at(i+1) == '!' || strParse.at(i+1) == '?')){
if(strParse.at(i+1) == '?'){
strParse.replace(i, 1, "?");
}
strParse.erase(i+1, 1);
len -= 1;
}
}
char strTemp[2000];
int lenTemp = strParse.copy(strTemp, i - pos + 1, pos);
strTemp[lenTemp] = '\0';
std::string strAdd(strTemp);
strList.push_back(strAdd);
pos = i + 1;
count ++;
}
}
if(count == 0){
strList.push_back(strParse);
}
return strList;
}
Your implementation of sentence parse is wrong, here is a simpler correct solution.
std::list<std::string> sentence_parse(const std::string &str){
std::string temp;
std::list<std::string> t;
for(int x=0; x<str.size();++x){
if(str[x]=='.'||str[x]=='!'||str[x]=='?'){
if(temp!="")t.push_back(temp);//Handle special case of input with
//multiple punctuation Ex. Hi!!!!
temp="";
}else temp+=str[x];
}
return t;
}
EDIT:
Here is a full example program using this function. Type some sentences in your console, press enter and it will spit the sentences out with a newline separating them instead of punctuation.
#include <iostream>
#include <string>
#include <list>
std::list<std::string> sentence_parse(const std::string &str){
std::string temp;
std::list<std::string> t;
for(int x=0; x<str.size();++x){
if(str[x]=='.'||str[x]=='!'||str[x]=='?'){
if(temp!="")t.push_back(temp);//Handle special case of input with
//multiple punctuation Ex. Hi!!!!
temp="";
}else temp+=str[x];
}
return t;
}
int main (int argc, const char * argv[])
{
std::string s;
while (std::getline(std::cin,s)) {
std::list<std::string> t= sentence_parse(s);
std::list<std::string>::iterator x=t.begin();
while (x!=t.end()) {
std::cout<<*x<<"\n";
++x;
}
}
return 0;
}
// This function should be easy to adapt to any basic libary
// this is in Windows MFC
// pass in a string, a char and a stringarray
// returns an array of strings using char as the separator
void tokenizeString(CString theString, TCHAR theToken, CStringArray *theParameters)
{
CString temp = "";
int i = 0;
for(i = 0; i < theString.GetLength(); i++ )
{
if (theString.GetAt(i) != theToken)
{
temp += theString.GetAt(i);
}
else
{
theParameters->Add(temp);
temp = "";
}
if(i == theString.GetLength()-1)
theParameters->Add(temp);
}
}