strcat function using char arrays - c++

The purpose of the following code was to create an strcat function using only basic array manipulation. A destination char array is input by a user and a source char array is appended to the end of it. My code works mostly fine except for the random chars it spits out for certain input char arrays. For example if I have my destination input as cheese and my source input as burger, the output is cheeseburger, as it should be. However if my destination input is dragon and my source input is fly, dragonfly should be the output. However, the output is given as dragonfly#. I have no idea what's wrong, and need help.
#include <iostream>
#include <string>
using namespace std;
void mystrcat ( char destination[], const char source[]);
int main(){
char source[80];
char destination[80];
cout << "Enter a word: ";
cin >> source;
cout << "\n";
cout << "Enter a second word: ";
cin >> destination;
mystrcat(destination, source);
}
void mystrcat ( char destination[], const char source[]){
int x=0;
for(int i=0; destination[i] != '\0'; i++)
{
if ( destination[i] != '\0')
{
x = x + 1;
}
}
for(int i=0; source[i] != '\0'; i++)
{
destination[i + x] = source[i];
}
cout << destination << endl;
}

Basically, you just need to add a null-character ('\0') at the end of the destination array.
Here is the correct (and slightly simplified) implementation:
void mystrcat(char destination[], const char source[])
{
int x = 0;
while (destination[x] != '\0')
{
x++;
}
for (int i=0; source[i] != '\0'; i++)
{
destination[x++] = source[i];
}
destination[x] = '\0';
}
But you should be aware that you have no safety-assertion on the size of the destination array...

You don't terminate the destination string. You need to add the '\0' character at the end.

short code:
void _mystrcat_(
__in char * out,
__in char * in)
{
while (*out) out++;
do { *out++ = *in++; } while (*in);
*out = 0x0;
}

Related

Is there a way I can fix this issue with length counter function?

I have to find the length of an array of characters using a function that uses the pointer notation and, for some reason, I get 23 but the result should be 5.
Here is the code I built:
#include <iostream>
using namespace std;
int length(char *N)
{
int length = 0;
char* S = N;
for (; *S != '\0'; S++);
for (; *N != *S; N++)
{
length++;
}
return length;
}
int main()
{
char A[5];
char *N;
N = A;
cout << "please enter the charecters you desire" << endl;
for (int i = 0; i <=4; i++)
{
cin >> A[i];
}
cout<<length(N);
}
You don't need two loops.
And note that you have to leave a space in the array (the last element) to fill it by '\0'.
Hence by the two notes and if you want to use five characters excluding the '\0', your code will be as follows
#include <iostream>
size_t length(char *N){
size_t length = 0;
for (; *N != '\0'; N++){
length++;
}
return length;
}
int main()
{
char A[6];
std::cout << "please enter the characters you desire\n";
for (int i = 0; i < 5; i++){
std::cin >> A[i];
}
A[5] = '\0';
std::cout << length(A);
}

Parallel vectors in C++

I need some help with the use of parallel vectors. What I want to do is have 2 vectors, 1 containing the alphabet, and the other containing the alphabet the other way around. When someone types in a word, it prints out the word using the inverted alphabet.
This is what I've done up until now and I'm not too sure if I'm on the right track or not:
#include <iostream>
#include <ctype.h>
using namespace std;
void search(char alfab[], char cripto[], int code){
cout << "Introduce your message: " << endl;
cin >> code;
for(int i = 0; i < code; i++)
{
if(code == 0){
cout << "Your code is:" << cripto[i] << endl;
}
}
}
int main(){
char alfab[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
char cripto[26] = {'z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'};
char code;
}
Think about how you would do this by hand. Then try to translate those steps to code.
Get user input
for each letter:
decide which letter of your reversed alphabet it is
write that new letter down in the same position as the original
output new string
Try something more like this instead:
#include <iostream>
#include <string>
static const char alfab[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
static const char cripto[26] = {'z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'};
std::string invert(const std::string &word){
std::string inverted = word;
for(std::string::size_type i = 0; i < inverted.size(); ++i)
{
char ch = inverted[i];
for(int j = 0; j < 26; ++j)
{
if (alfab[j] == ch)
{
inverted[i] = cripto[j];
break;
}
}
}
return inverted;
}
int main(){
std::string word;
std::cout << "Enter a word: " << std::endl;
std::cin >> word;
std::cout << "Your code is: " << invert(word) << std::endl;
}
You could try using one array:
std::string invert(const std::string& original)
{
static const char cripto[26] =
{
'z','y','x','w',
'v','u','t','s','r',
'q','p','o','n','m',
'l','k','j','i','h',
'g','f','e','d','c',
'b','a'
};
const size_t length = original.length();
std::string inverted_text;
for (unsigned int i = 0; i < length)
{
char c = original[i];
inverted_text += cripto[c - 'a'];
}
return inverted_text;
}
Edit 1: Using some math
You could simplify the encryption (inversion) by using some math.
std::string invert(const std::string& original)
{
const size_t length = original.length();
std::string inverted_text;
for (unsigned int i = 0; i < length)
{
char c = original[i];
inverted_text += (25 - (c - 'a')) + 'a';
}
return inverted_text;
}
Using transform
You could use std::transform:
char invert_char(char c)
{
return (25 - (c - 'a')) + 'a':
}
//...
std::transform(original_word.begin(), original_word.end(),
original_word.begin(), invert_char);

copying one element of a char array to another using for loop

I'm trying to write a simple program which takes an array of chars, and spits it out backwards. I know there are plenty of other ways to shorten this using a library header function, but I wanted to do it using for loops just to get used to them.
#include<stdio.h>
#include<iostream>
using namespace std;
char string1[10];
int count = 0;
char stringy[10];
void enterString()
{
cout << "please enter a string: " << endl;
cin >> string1;
}
void stringCounter(const char stringLength[])
{
//initiate for loop i = 0
//if stringLength[i] does not does not equal 'i' then carry on
//increment i
for (int i = 0; stringLength[i] != '\0'; i++)
{
count++;
}
cout << "size of string is: " << count << endl;
}
void reverseString(int arraySize, char string2[])
{
int counter = 0;
for (int i = arraySize; i >= 0; string2[i--])
{
stringy[counter] = string2[i];
counter++;
}
stringy[count] = '\0';
cout << stringy << endl;
}
int main()
{
enterString();
stringCounter(string1);
reverseString(count, string1);
return 0;
}
This is the whole program. The program is failing in function reverseString. I can't work out how to successfully read the last index of the char array string2[] and copy it into the first index of char array stringy.
One, If the user enters a string more than 10 characters long then your enterString() function will access the array out of its bound, at cin>>string1. So better to use getline to make sure you don't read more than what your array can hold.
Two, with your current implementation the reverseString() function will write to the first element of the array with the null terminator character,if the arraySize<=10, and trying to display that string will not show you anything.
This:
cin >> string1;//will try to access the array out of its bound if user give more than it can hold,i.e 10 characters
...
for (int i = arraySize; i >= 0; string2[i--])
{
stringy[counter] = string2[i];//the first iteration will put the '\0' character as the first elements of stringy
counter++;
}
Should be changed to:
cin.getline(string1,10);//make sure to get not more than 10 characters,including the null terminator
.....
for (int i = arraySize-1; i >= 0; i--)
{
stringy[counter] = string2[i];
counter++;
}
There are many mistakes in your program. If this is the exact code you are compiling then it should throw many errors.
Following might help.
#include<iostream>
using namespace std;
void reverseString(int , char *);
int stringCounter(const char );
int stringCounter(const char stringLength[])
{
int count = 0;
for (int i = 0; stringLength[i] != '\0'; i++)
count++;
cout << "size of string is: " << count << endl;
return count;
}
void reverseString(int arraySize, char string2[])
{
int counter = 0;
char stringy[100];
for (int i = arraySize - 1; i >= 0; i--)
{
stringy[counter] = string2[i];
counter++;
}
stringy[counter] = '\0';
cout << stringy << endl;
}
int main()
{
char str[] = "string";
reverseString(stringCounter(str),str);
return 0;
}

Buffer overload Error(C++ Visual Studios)

This is my code to read a file and store some lines from a position in the file and save it to an char array.
The code works fine , if i call getVNP() once in the main.
However when i try calling it the second time , I encounter a buffer overload error.
I tried searching , but I haven found a solution please help thanks.
#include <iostream> // library that contain basic input/output functions
#include <fstream> // library that contains file input/output functions
#include <string>
using namespace std;
void getVNP(std::string fileName, char* outStr)
{
int end;
int start;
char sWord[] = "Virtual";
char eWord[] = "[Default";
int position = 0; //this will be used incremental to fill characters in the array
int sWord_size = 0;
int eWord_size = 0;
//this loop is calculating the length of input word
for (int i = 0; sWord[i] != '\0'; i++)
{
sWord_size++;
}
for (int i = 0; eWord[i] != '\0'; i++)
{
eWord_size++;
}
fstream fin(fileName.c_str());
fin.seekg(0, fin.end);
int epos = fin.tellg();
fin.seekg(0, fin.beg);
cout << epos;
int array_size = epos; // define the size of character array
char * array = new char[array_size]; // allocating size an array
//opening an input stream for file test.txt
/*checking whether file could be opened or not. If file does not exist or don't have read permissions, file
stream could not be opened.*/
if (fin.is_open())
{
//file opened successfully so we are here
cout << "File Opened successfully!!!. Reading data from file into array" << endl;
//this loop run until end of file (eof) does not occur
while(!fin.eof() && position < array_size)
{
fin.get(array[position]); //reading one character from file to array
position++;
}
array[position - 1] = '\0'; //placing character array terminating character
//this loop is searching for the word in the array
for (int i = 0; array[i] != '\0'; i++)
{
for (int j = 0; sWord[j] != '\0' && j < 20 ; j++)
{
if (array[i] != sWord[j])
{
break;
}
else
{
i++;
if (sWord[j + 1] == '\0')
{
start = i-sWord_size+23;
}
}
}
}
for (int i = 0; array[i] != '\0'; i++)
{
for (int j = 0; eWord[j] != '\0' && j < 20 ; j++)
{
if (array[i] != eWord[j])
{
break;
}
else
{
i++;
if(eWord[j + 1] == '\0')
{
end = i-eWord_size - 11;
}
}
}
}
//take the start pos and the end pos text and put in string array s;
fin.seekg(start);
char *s = new char[end - start + 1];
fin.read(s, end - start);
s[end - start] = 0;
size_t len = strlen(s);
for(int i=0; i <len; ++i)
{
outStr[i] = s[i];
}
fin.close();
}
else //file could not be opened
{
cout << "File could not be opened." << endl;
}
getchar();
}
int main()
{
std::string FilePath;
std::string FilePath2;
char aConfig[] = " ";
char bConfig[] = " ";
std::cout << "Please enter a file path: ";
std::cin >> FilePath;
std::cout << "Please enter a second file path: ";
std::cin >> FilePath2;
getVNP(FilePath, aConfig);
cout << aConfig;
getVNP(FilePath2, bConfig);
cout << bConfig;
getchar();
return 0;
}
Your char aConfig[] is an array with 2 indices. The first one is the space and the second one \0 to indicate the end of the array.
If your path is longer than 1 letter, you should either dynamically allocate this, pass the function a std::string by reference, or use the MAX_PATH define (thought I recommend the std::string solution).
void getVNP(std::string fileName, std::string &outStr);
Also you should clean up if you allocate something with new. This is not java.
In main
char aConfig[] = " ";
creates array char[2] (space and null at the end). The second one (bConfig) creates another array char[2].
In getVNP
outStr[i] = s[i];
You are writing to this static array while you have only place for 2 characters.
Condider changing aConfig and bConfig to std::string or allocating bigger buffer (char aConfig[255];).

concatenating two strings c++

im trying to stick two strings together without using + operator,also using loops to to that.the problem is after when it read two strings it couldnt print the second string and only the first string appears.
here is my code
this code is like copying two strings in one.
char str1[MAX];
char str2[MAX];
cout<<"Enter The first String:\n";
cin.getline(str1,MAX,'\n');
cout<<"Enter the second String:\n";
cin.getline(str2,MAX,'\n');
char str3[2*MAX]; int k=0;
for(int i=0;i<MAX;i++)
{ str3[k]=str1[i]; k++; }
for(int j=0;j<MAX;j++)
{ str3[k]=str2[j]; k++; }
str3[k]='\0';
cout<<endl<<"Here is the concatenated string:\n";
cout<<str3<<endl;
It is better to write such code using pointers.
So I would substitute this wrong code
char str3[2*MAX]; int k=0;
for(int i=0;i<MAX;i++)
{ str3[k]=str1[i]; k++; }
for(int j=0;j<MAX;j++)
{ str3[k]=str2[j]; k++; }
str3[k]='\0';
for the following
char str3[2 * MAX];
char *p = str3;
char *q = str1;
while ( *p = *q++ ) ++p;
q = str2;
while ( *p++ = *q++ );
Also the same can be written using for loops. For example
char str3[2 * MAX];
char *p = str3;
for ( char *q = str1; *p = *q++; ++p );
for ( char *q = str2; *p++ = *q++; );
Your code goes past the end of str1 and str2, including their null terminators. Once the null terminator of srt1 is copied, C string inside str3 is considered complete, so str2 part is ignored.
You need to modify the first loop to stop once it sees '\0' in str1, and copy str2 from that point on. Do the same for the second loop. Your code adds null termination already, so the result will be correct:
for(int i=0;i<MAX && str1[i] != '\0';i++)
{ str3[k]=str1[i]; k++; }
for(int j=0;j<MAX && str2[j] != '\0';j++)
{ str3[k]=str2[j]; k++; }
Note: I am assuming that this is a learning exercise for which you are not allowed to use std::string.
Correct code should be:-
char str3[2*MAX];
int k=0;
for(int i = 0; str[i] != '\0'; i++)
{
str3[k]=str1[i];
k++;
}
for(int j=0 ; str2[j] != '\0'; j++ )
{
str3[k] = str2[j];
k++;
}
str3[k]='\0';
You were not taking into account null terminator and hence reading past that.
Change this :
for(int i=0; str1[i] ;i++)
{ str3[k]=str1[i]; k++; }
for(int j=0; str2[j] ;j++)
{ str3[k]=str2[j]; k++; }
You have to stop concatenating when str1 or str2 ends that is when str1[i] or str2[j]
will be 0 ('\0'). But you were looping through MAX. That's why your program produced wrong output.
Hope you understand now :)
#dasblinkenlight explains why this doesn't work in her/his answer.
Here's yet another solution using the standard C(++) library function strcat defined in . See http://www.cplusplus.com/reference/cstring/strcat/
#include <iostream>
#include <cstring>
using namespace std;
int main(int argc, char** argv) {
char str1[MAX];
char str2[MAX];
cout << "Enter The first String:" << endl;
cin.getline(str1, MAX);
cout << "Enter the second String:" << endl;
cin.getline(str2, MAX);
char str3[2 * MAX];
strcat(str3, str1);
strcat(str3, str2);
cout << endl << "Here is the concatenated string:" << endl
<< str3 << endl;
}