How do i convert a string to an int array after parsing? - c++

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++;
}
}

Related

filling 2d char array and accessing each element

It's my first question in stack overflow so if there is some mistakes sorry about that. I'm trying to fill a 2d char array and then access each letter. I complied my code, there is no error but when I try to run it doesn't work. Here it's my code.
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
int main() {
char ch[] = "Welcome text in a separate line.";
char strWords[5][7];
int counter = 0;
int a = 0;
for (int i = 0; i < sizeof(ch); i++) {
if (ch[i] == ' ') {
strWords[counter][a] = '\0';
counter++;
a = 0;
}
else
{
strWords[counter][a] += ch[i];
a++;
}
}
for (int i = 0; i <= 5; i++) {
for (int a = 0; a <= 7; a++) {
cout << strWords[i][a] << " ";
}
}
return 0;
}
A few things wrong with your code
int main() {
char ch[] = "Welcome text in a separate line.";
// char strWords[5][7]; <<<=== i would change to be larger that you need, just in case
char strWords[20][20];
int counter = 0;
int a = 0;
for (int i = 0; i < strlen(ch); i++) { // sizeof is wrong, you need strlen
if (ch[i] == ' ') {
strWords[counter][a] = '\0';
counter++;
a = 0;
}
else
{
//strWords[counter][a] += ch[i];
strWords[counter][a] = ch[i]; // you do not need to try to concatenate, you are already walking down the buffer with 'a'
a++;
}
}
for (int i = 0; i < counter; i++) { // use 'counter' as it has the number of lines
// since you 0 terminated the string you do not need to walk character by character
cout << strWords[i] << " ";
}
return 0;
}
You are also not detecting and terminating the last word (since there is no space after it). I will leave that to you. The code I show does not print the word 'line.'
You should really have tests to make sure you do not overflow the length or number of words.
Plus you should ideally use std::string and std::vector
Note - if, for experimentation, you do want to walk through char by char to output the strings you should look for the terminating '0' character and exit the inner loop

how to find the length of the string on the array?

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;
}

Run length encoding in C++

#include <iostream>
#include <string>
#include <vector>
using namespace std;
string compression(const string & str){
int i = str.size();
string letters;
letters[0] = str[0];
for (int j = 0; j < i; ++j){
int count = 1;
while (str[j] == str[j+1]){
count++;
j++;
}
letters.push_back('0' + count);
letters.push_back(str[j]);
}
return letters;
}
int main(){
string input;
char c;
try {
cout << "Enter the data to be compressesed: "<< endl;
cin >> input;
for (int z = 0; z < input.length(); ++z){
c = input.at(z);
}
if (!(c >= 'a' && c <= 'z')){
throw runtime_error("error: invalid input");
}
}
catch (runtime_error& excpt){
cout << excpt.what() <<endl;
return 0;
}
cout << "The compressed data is " << compression(input) << endl;
return 0;
}
The expected output is , repeated for each run of characters. Here is the amount of times is repeated in sequence.
Some examples:
aaeeeeae = 2a4e1a1e
rr44errre = invalid input
eeeeeeeeeeeeeeeeeeeee = 21e
the code works properly only if the character is repeated consecutively 9 times or less. for values of 10 and more the input is other symbols.
For example it stays blank for 10, so if input is 'aaaaaaaaaabb',output just would be 'a2b' instead of '10a2b'. For 11 its outputs ';',
so if input is 'aaaaaaaaaaabb', output is ';a2b' for some reason.
So my question is, how do i make the pushback work for all numbers and not just from 0-9?
Thank you for your time if u've gotten to here. ^^
If you can use c++11 or newer your function compression could look like:
string compression(const string & str){
int i = str.size();
string letters;
for (int j = 0; j < i; ++j){
int count = 1;
while (str[j] == str[j+1]){
count++;
j++;
}
letters += std::to_string(count);
letters.push_back(str[j]);
}
return letters;
}

What is the difference between these two loops in C++?

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.

C++ merging text using pointers

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;
}