I am trying to learn some of this beautiful language but I've got stuck on this. Problem is: Why does the last count shows only Witaj PJC not Witaj Cpp PJC? As you see function app has to append transformed 2nd word to 1st one.
Thanks for any help.
If you could give me any good tutorial about pointers I would appreciate that. Thanks!
#include <iostream>
#include <string.h>
using namespace std;
void app(char *str2, char *str1){
for(int i =0; i < strlen(str2); i++){
*(str2++);
}
for(int i =0; i < strlen(str1); i++){
*(str1++);
}
for(int i =0; i < strlen(str1); i++){
*(str2)=*(str1);
*(str2)++;
*(str1)--;
}
}
int main()
{
char *str1 = "ppC ";
char str2[20] = "Witaj";
cout << str2 << endl; // Witaj
app(str2, str1);
cout << str2 << endl; // Witaj Cpp shows WitCpp
app(str2, "CJP ");
cout << str2 << endl; // Witaj Cpp PJC shows WitPJ
return 0;
}
Your problem is this sort of loops:
for(int i =0; i < strlen(str2); i++){
*(str2++);
}
You can't move your pointer with str2++ and expect that strlen(str2) still returning the lenght of the original one.
For loop variables, in each iteration:
i str2 strlen(str2) condition
Iteration 1 0 Witaj 5 0 < 5 Ok
Iteration 2 1 itaj 4 1 < 4 Ok
Iteration 3 2 taj 3 2 < 3 Ok
Iteration 4 3 aj 2 3 < 2 Exit at 3rd character!!
Thus.. you only "move" your pointer 3 bytes.
Change your app function for that one:
void app(char *str2, char *str1){
int nstr2 = strlen(str2);
int nstr1 = strlen(str1);
for(int i =0; i < nstr2; i++){
*(str2++);
}
for(int i =0; i < nstr1; i++){
*(str1++);
}
for(int i =0; i < nstr1; i++){
*(str2++)=*(--str1);
}
}
Anyway... this program is only for academic porpouses or you are thinking use it professionally?
And for some functioning code for just string appending, i scribbled this...
Note that you should make a const call instead, and if you want to reverse one of the strings (a bit unclear from your question) it should be done prior to appending.
Example of string append (rather unsafely and rudimentary) using a new allocation:
char* app(char *str2, char *str1){
char* appendedstring = (char*)malloc(sizeof(char)*20);
char *temp = str1;
char *temp2 = str2;
int stringlen1 = strlen(str1);
int stringlen2 = strlen(str2);
//Copy string 1
for (int i = 0; i < stringlen2; i++){
appendedstring[i] = *temp2;
temp2++;
}
//Append string 2
for (int i = 0; i < stringlen1 + 1; i++){
appendedstring[stringlen2 + i] = *temp;
temp++;
}
return appendedstring;
}
int main()
{
int t;
char *str1 = "ppC ";
char str2[20] = "Witaj";
cout << str1 << endl;
cout << str2 << endl; // Witaj
char* newstr = app(str2, str1);
cout << newstr << endl; // Witaj Cpp shows WitCpp
char* newstr2 = app(str2, "CJP ");
cout << newstr2 << endl; // Witaj Cpp PJC shows WitPJ
return 0;
}
Related
I'm trying to get the length of the string from a char array
My input is:alpha kian namikian and the output should be 5 4 8 but at the moment my output is 11 11 11 11 11 11 11 11 11 11 11 which is not what I'm trying to achieve.
int i,count;
char str[100];
cout<<"enter string\n";
for(i=0;;i++)
{
cin>>str[i];
if(cin.get()=='\n')
{
count=i+1;
break;
}
}
for(i=0;i<count;i++)
{
int len = strlen(str);
cout<<len<<"\n";
}
You have a compilation error because you're trying to fit an array of strings as a parameter to strlen. In your code, str contains all the strings, so you have to use access operator [] just like you did when you were taking strings from standard input.
int len = strlen(str) becomes int len = strlen(str[i]) and that should fix the error.
EDIT:
It looks like you can't use strlen with strings. Use length() instead.
int len = str[i].length()
EDIT #2:
Adding full code for reference with output:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i, count;
string str[100];
cout << "enter string\n";
for (i = 0;; i++)
{
cin >> str[i];
if (cin.get() == '\n')
{
count = i + 1;
break;
}
}
for (i = 0; i < count; i++)
{
int len = str[i].length();
cout << len << "\n";
}
}
Output:
enter string
alpha kian namikian
5
4
8
You can use this approach using the vector type string and exit the storing of the strings if entered string is exit
I am using a temp variable to store the string at any index and output the corresponding length.
int i;
vector<string> str;
cout << "Enter String\n";
while(cin)
{
string temp;
cin >> temp;
if(temp == "exit")
break;
else
str.push_back(temp);
}
int n= str.size();
for(i = 0; i< n; i++)
{
string temp = str[i];
int len = temp.length();
cout << len << endl;
}
I am trying to convert a string that I have already parsed with spaces into a int array:
//example of string before parsing
arrElement = "1,2,3";
//parsing
for(int i =0; i < size; i++){
if(arrElements[i] == ','){
arrElements[i] = ' ';
}
}
//string is now "1 2 3"
//trying to convert numbers only into int
stringstream str;
int intCount = 0;
int intNum[size];
for(int i = 0; i < size; i++){
str << arrElements[i];
if(str == " ") {
}
else {
str >> intNum[intCount];
intCount++;
}
}
I am currently getting the result there are five integers reads, instead of the three in the example I made. In addition when I print out the array, I am completely different numbers:
209664128 32764 0 0 0
I sort of understand the issue, but I am new c++ so I could be wrong, and I am unsure how to resolve this issue. Any help would be greatly appreciated.
Here are some minimal modifications to make your example working.
I think you should avoid the successive calls between std::stringstream::operator>> and std::stringstream::operator<<.
//example of string before parsing
std::string arrElements = "1,2,3";
//parsing
for(int i =0; i < arrElements.size(); i++){
if(arrElements[i] == ','){
arrElements[i] = ' ';
}
}
//string is now "1 2 3"
//trying to convert numbers only into int
stringstream str(arrElements);
int intCount = 0;
static const int size = 3;
int intNum[size];
for(int i = 0; i < size; i++){
if(str == " ") {
}
else {
str >> intNum[intCount];
intCount++;
}
}
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;
}
what is the difference between these two loops? I was working on a few competitive programming challenges, everytime I was using the first loop variant I was failing and when i changed it to the second kind of loop it passes all the tests:
Loop variant 1:
for(int j=0; j<str1.length() ; j++) {
char ch = str1[j]
int diff = ch-'a';
arr1[diff]++;
}
Loop variant 2:
for(int i =0; i<str1.length() ;i++) {
arr1[str1[i]-'a']++;
}
I understand that this is a silly question but please be patient, I just want to be clear about why the first one is not working.
Example: Find the minimum number of character deletions required for two given strings to be anagrams
Input:
cde
abc
Output:
4
Incorrect Code
void minDeletions(string str1, string str2) {
if(str1 == str2){
cout << 0 << endl;
return;
}
int arr1[26] = {0};
int diff,diff1;
for(int i =0; i<str1.length() ;i++) {
char ch = str1[i];
diff = ch-'a';
arr1[diff]++;
}
int arr2[26] = {0};
for(int j=0; j<str2.length() ; j++) {
char ch = str2[j];
diff1 = ch-'a';
arr2[diff]++;
}
int count = 0;
for(int k=0; k<26 ; k++){
if(arr1[k]!=arr2[k]){
count += abs(arr1[k]-arr2[k]);
}
}
cout << count << endl;
}
int main() {
string str1,str2;
cin >> str1;
cin >> str2;
minDeletions(str1,str2);
return 0;
}
Example of test case that fails
Input:
fcrxzwscanmligyxyvym
jxwtrhvujlmrpdoqbisbwhmgpmeoke
Output:
30
Cant this be it? Compared to the second loop variant, that works fine, there is no explicit int diff here that is a source of confusion (see below):
int arr1[26] = {0};
int diff, diff1;
for(int i = 0; i < str1.length() ; i++){
char ch = str1[i];
diff = ch - 'a';
// ^^^^
arr1[diff]++;
// ^^^^
}
int arr2[26] = {0};
for(int j = 0; j < str2.length() ; j++){
char ch = str2[j];
diff1 = ch - 'a';
// ^^^^^
arr2[diff]++;
// ^^^^
}
P.S. Look closely, both loops use the same index! I.e. it's not updated in the second loop after it gets a value in the first loop.
I have problem with "tab" output. My program is going to show part sums.
I want to save those part sums in tab array but it shows only first sum.
here is code I wrote:
const char numbers[] = { "1 2 3 4" };
cout << numbers << endl;
for (int i = 0; i < strlen(numbers); ++i)
{
if (numbers[i] != ' ') cout << numbers[i] << endl;
}
int sum = 0;
char tab[20];
for (int i = 0; i < strlen(numbers); ++i){
if (numbers[i] != ' ') {
sum += atoi(&numbers[i]);
_itoa_s(sum,&tab[i],sizeof(tab),10);
}
}
cout << tab;
_getch();
return 0;
How I can make it to show proper part sums like: 1 3 6 10
sizeof shows the size of the array in bytes, not the number of elements in the array.
Something like this will give you the number of elements:
int num_element = sizeof(numbers)/sizeof(numbers[0]);
Or a full solution:
const char numbers[] = { "1 2 3 4" };
int num_elements = sizeof(numbers)/sizeof(numbers[0]);
cout << numbers << endl;
for (int i = 0; i < num_elements; ++i)
{
if (numbers[i] != ' ') cout << numbers[i] << endl;
}
int sum = 0;
char tab[20];
for (int i = 0; i < num_elements; ++i){
if (numbers[i] != ' ') {
sum += atoi(&numbers[i]);
_itoa_s(sum,&tab[i],sizeof(tab),10);
}
}
cout << tab;
_getch();
return 0;
Although the above should work after replacing num_element into your for loops, I suggest you looking into a std::array or std::vector
Your code has several problems. The first one is that function atoi will return an error because is will consider all string starting from &numbers[i] till the terminating zero. The other problem is that this in expression
_itoa_s(sum,&tab[i],sizeof(tab),10);
using tab[i] is incorrect.
Try the following code.
#include <iostream>
#include <cstring>
#include <cctype>
#include <cstdio>
//...
const char numbers[] = { "1 2 3 4" };
char tab[20];
char *p = tab;
int sum = 0;
for ( size_t i = 0, n = std::strlen( numbers ); i < n; i++ )
{
if ( std::isdigit( numbers[i] ) )
{
sum += numbers[i] - '0';
p += std::sprintf( p, "%d ", sum );
}
}
std::cout << tab << std::endl;
At least I got output
1 3 6 10
Also it would be better to use std::istringstream instead of the for loop where you are extracting digits.
You are not retrieving the size of your arrays here.
Use SIZEOF_ARRAY to get the size of numbers in C.
But you tagged C++, so consider using std::array<> instead of a C-style array (it will expose the size of the array for you)
Firstly, cout << tab; prints only the first element.
Secondly, instead of writing the result to tab[i], create int cnt = 0; _itoa_s(sum,&tab[cnt],sizeof(tab),10); cnt++ By that way, you won't have empty characters in you tab array.
Thirdly, you can keep int tab[20], rather than to keep in char tab[].
Forthly, int num_elem = sizeof(numbers)/sizeof(numbers[0]);(as said above).