Okay. I have taken a sentence and split into an array thus far with this code I found online:
string strWords[5];
short counter = 0;
for(short i =0; i<texttoChange.length();i++)
{
strWords[counter] +=texttoChange[i];
if(texttoChange[i] == ' ')
{
counter++;
}
}
for(short i=0;i<5;i++)
{
cout << strWords[i] << "(" << strWords[i].size() << ")" << endl;
}
Now I want to take strWords[i] and split that array into an array of characters or single letter string array. Is it Possible?
Assuming you need a c style array, you can do,
char *charArray = strWords[i].c_str();, you can get the size by strlen(charArray)
otherwise there is no point of converting string to char array.
Related
In the following code the length of the reversed string is being returned as zero which should not be the case:
int main() {
string for_reversal;
string reversed;
int i,j,length, r_length;
cout << "Enter the string : \n";
cin >> for_reversal;
cout << "Entered string is : " << for_reversal <<"\n";
cout << "String length is : " << for_reversal.length() << "\n";
length = for_reversal.length();
for (i=0; i<=length; i++)
{
reversed[i] = for_reversal[length - i-1];
cout << for_reversal[length-i] << "\t";
}
reversed[length+1]='\0';
cout << "\n";
r_length = reversed.length();
cout << "Reversed String length is : " << r_length << "\n";
cout << "Reversed String is : " << reversed;
return 0;
}
Not sure whats going wrong here.
There are length valid characters in a string with length length. In your cycle you access the element with index length which is out of bounds for the string and this invokes undefined behavior.
Additionally you can not assign values to cells in a string that are outside of its current size, while you assign values to the cells in reversed before resizing the string appropriately. This leads to second undefined behavior.
Having in mind the two issues I mentioned above the behavior of your problem is really not defined. However the output does makes sense if we ignore that - you assign to reversed[0] the value of for_reversal[length], which is probably '\0'. As a result the length of reversed is now 0.
Change
reversed[i] = for_reversal[length - i-1];
to
reversed+=for_reversal[length - i-1];
The way you're doing it is accessing the string out of its bound, paving the way for all kinds of hell breaking through. They way proposed above will append stuff to the string, reserving space as needed.
You could try and reserve space in "reversed" (http://www.cplusplus.com/reference/string/string/reserve/) so it can hold the original string (reversed.reserve(for_reversal.size())).
In any case, please not that you're not reserving space for the \0 character. Either reserve a bigger string or append \0 with the + operator.
The problem is here:
for (i = 0; i <= length; i++) {
reversed[i] = for_reversal[length - i-1];
// ...
}
With the statement:
reversed[i]
You're actually trying to access the i-th element of the string, with i=0, 1, ..., length.
But at that moment, the object string reversed is an empty string. Indeed you've created it with:
string reversed;
That is default constructor which initializes an empty string.
In other words, reversed[i] access to undefined memory location, since reversed is void, and there is no i-th position in the string.
Solution
In order to reverse a string you may find this code useful:
std::string reversed;
for(auto rit = for_reversal.rbegin(); rit != for_reversal.rend(); ++rit) {
reversed.push_back(*rit);
}
This code should be safer that your, using iterators (in that case reversed iterator).
Note
Moreover there is no need to append the '\0' char at the end, because the class string already handles that.
The program has undefined behavior because the string reversed is empty
string reversed;
and you may not use the subscript operator
reversed[i] = for_reversal[length - i-1];
^^^^^^^^^^^
to assign values to the string.
Also there is no need to append the zero character to objects of type std::string.
Take into account that in the loop
for (i=0; i<=length; i++)
{
reversed[i] = for_reversal[length - i-1];
cout << for_reversal[length-i] << "\t";
}
then i is equal to length then you will have
reversed[length] = for_reversal[-1];
^^^^^
The simplest way to create a reversed string is the following
#include <iostream>
#include <string>
int main()
{
std::string for_reversal;
std::cout << "Enter the string: ";
std::cin >> for_reversal;
std::string reversed( for_reversal.rbegin(), for_reversal.rend() );
std::cout << "\nReversed String length is : " << reversed.length() << "\n";
std::cout << "Reversed String is : " << reversed << std::endl;
return 0;
}
The program output is
Enter the string: Hello
Reversed String length is : 5
Reversed String is : olleH
If you want to write the loop yourself then you should reserve enough memory in the reversed string or at least use member function push_back instead of the subscript operator if the string initially is empty. The program can look for example the following way
#include <iostream>
#include <string>
int main()
{
std::string for_reversal;
std::string reversed;
std::cout << "Enter the string: ";
std::cin >> for_reversal;
reversed.reserve( for_reversal.length() );
for ( std::string::size_type i = for_reversal.length(); i != 0; i-- )
{
reversed += for_reversal[i-1];
}
std::cout << "\nReversed String length is : " << reversed.length() << "\n";
std::cout << "Reversed String is : " << reversed << std::endl;
return 0;
}
The program output will be the same as shown above
Enter the string: Hello
Reversed String length is : 5
Reversed String is : olleH
first initialize string reversed with empty string i.e string reversed="";
after this change for loop:
for(int i=0;i<length;i++)
{
reversed+=for_reversal[length-1-i];
cout << for_reversal[length-i] << endl;
}
int r_length=reversed.length();
cout << "reversed string length : " << r_length << endl;
cout << "Reversed string is : " << reversed << endl;
hope u understand.
I am taking inputs in 2D-Array. i.e--
forward 50 back 20
I want to copy "forward" in simple char array[], "50" in char array[] (each string in each char array[])
I am only able to store first element in first array.
I've tried storing index of "space" and then storing the integer values until "another space "\n" found in 2d-array, but it stored only first string (forward) in all the char arrays i ran loop on...
Here's the code i was checking on.
for (int j=0; arr[1][j] != ' '; j++)
{
check[m] = arr[1][j];
m++;
}
check[m] = '\0';
int k = 0;
cout << check << endl;
if (arr[1][m] == ' ')
{
for (;arr[1][m] == ' ';)
{
m++;
cout << arr[1][m];
value[k] = arr[1][m];
k++;
}
}
value[k] = '\0';
From your comments it seems as though this might should actually be a C question and not a C++ question.
But since this is homework anyway maybe seeing a C++11 solution will get you moving in the right direction.
const char* arr[]{"forward ", "50 ", "back ", "20"};
const string check = accumulate(cbegin(arr), cend(arr), string());
After this check will contain "forward 50 back 20".
Live Example
I have problem in my split Sentence function .
The idea of ​​my function split any Sentence and add it to array like
Example:
Sentence:: Hello world.
My function will works:: (array[0]= hello, array[1]= world).
This is my code
void splitSentence(char *Sentence, char symb){
const int Size = strlen(Sentence);
string SentenceResult[2];
int count= 0;
stringstream stream;
for(int i=0;i<Size;i++){
stream << Sentence[i];
if((Sentence[i] == symb) || (Sentence[i] == '\0')){
SentenceResult[count] = stream.str();
count++;
stream.str(" ");
}
}
cout << "Stream: " << stream.str() << endl;
cout << "Word [0]: " << SentenceResult[0] << endl;
cout << "Word [1]: " << SentenceResult[1] << endl;
}
The result
Stream: world
array [0]: hello
array [1]: // empty (must be "world")
What the problem in my function.
Why array[1] is empty .
const int Size = strlen(Sentence);
This calculates the length of the string data, but not the final null terminator, so your loop will not find the terminator, and won't include the last word. You want to add one to this value to get the full length of the terminated string.
Your for loop does not run far enough to get to the Sentence[i] == '\0' case. It will only run up to the "d" of "hello world", so the conent of the stream is not written anymore into the output array.
You could for example write:
const int Size = strlen(Sentence)+1;
and you have included the final null byte.
You just need to change your for loop:
for(int i=0; i <= Size; i++)
I'm just starting out programming but I've had a lot of ideas about how to make my life easier when parsing files by making a program that maps addresses of data when read into memory from a file.
Note: I cut down the wall text here's the problem in a nutshell
How does one parse an array of chars with no null terminator but the words all begin with uppercase letters so Capital can be used as delimiter?
Basically I want to parse text file that is just 'WordWordWord' and send each word to a to it's own separate string variable then be able to write each word to a text file with a newline added.
I wanted to do some more advanced stuff but I was asked to cut the wall of text so that will do for now :)
//pointers and other values like file opening were declared
int len = (int) strlen( words2 );
cout << "\nSize of Words2 is : " << len << " bytes\n";
// Loops through array if uppercase then...
for (int i = 0; i < len; i++)
{
if (isupper(words2[i]))
{
// Output the contents of words2
cout << "\n Words2 is upper : " << words2[i] << "\n";
b1 = &words2[i];
//output the address of b1 and the intvalue of words2[var]
cout << "\nChar address is " << &b1 << " word address is " << (int) words2[i] << "\n";
cout << "\nChar string is " << b1 << " address +1 "<< &b1+1 <<"\n and string is " << b1+1 << "\n";
}
cout << "\nItem I is : i " << i << " and words2 is " << words2[i] << "\n";
}
fin.clear();
fin.close();
fout.close();
Easy. Use Boost.Tokenizer, with char_separator("", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"). "" is the set of dropped separators, and A-Z is the set of kept separators. (If you'd used A-Z as dropped separators, you'd get ord ord ord because you'd drop the W.)
Since you also
wanted to do some more advanced stuff
I would have a look a Boost.Regex from the get go. This is a good library for doing textual manipulations.
vector<char *> parsedStrings;
char * words = "HelloHelloHello";
int stringStartAddress = 0;
for (int i = 0; i <= strlen(words); i++)
{
/* Parses word if current char is uppercase or
if it's the last char and an uppercase char was previously matched */
if (isupper(words[i]) || ((i == strlen(words)) && (stringStartAddress != 0)))
{
// Current char is first uppercase char matched, so don't parse word
if (stringStartAddress == 0)
{
stringStartAddress = ((int)(words + i));
continue;
}
int newStringLength = ((int)(words + i)) - stringStartAddress;
char * newString = new char[newStringLength + 1];
// Copy each char from previous uppercase char up to current char
for (int j = 0; j < newStringLength; j++)
{
// Cast integer address of char to a char pointer and then get the char by dereferencing the pointer
// Increment address to that of the next char
newString[j] = *((char *)stringStartAddress++);
}
newString[newStringLength] = '\0'; // add null-terminator to string
parsedStrings.push_back(newString);
}
}
I'm working on a small little thing here for school. After hours of researching, and a ton of errors and logic reworking I've almost completed my little program here.
I'm trying to take user input, store it into the string, get a character array from the string ( dont ask why, I just have to put this into a character array ), then get the reversed order of the phrase that the user entered. Here is my code:
#include "stdafx.h"
#include <iostream>
#include <String>
#include <cstring>
using namespace std;
using namespace System;
#pragma hdrstop
char* getCharArray(string);
string reversePhrase( int, char* );
void main(void)
{
string sPhrase = "";
int sSize = 0;
string sReversed = "";
char* cPhrase = NULL;
cout << "Welcome to the You Type It & We'll Reverse it! [Version 1.0] " << endl;
cout << "This program will reverse your phrase, and count how many characters are in it!" << endl;
cout << "To begin just enter a phrase." << endl;
cout << "Enter a phrase: ";
getline( cin, sPhrase);
sSize = sPhrase.length();
cout << endl;
cPhrase = getCharArray(sPhrase);
sReversed = reversePhrase( sSize, cPhrase );
cout << sReversed;
system("pause");
}
string reversePhrase(int size , char* cPhrase)
{
string sReversed = "";
int place = size;
for ( int i = 0; i < size ; i ++ )
{
sReversed.append(1, cPhrase[place]);
cout << "Current string: " << sReversed << endl;
cout << "Current character: " << cPhrase[place] << endl;
place--;
}
return sReversed;
}
char* getCharArray(string sPhrase)
{
int size = 1;
size = sPhrase.length();
char* cArray = NULL;
cArray = new char[size];
for (int i = 0 ; i < size ; i++)
{
cArray[size] = sPhrase.at(i);
}
return cArray;
}
When I type in "ownage" into the program, this is what I get returned:
It is almost like my Character Array is getting garbage collected before it can use all of the characters. This is probably an easy fix but, I just don't see how I can get around this one.
Try rewriting getCharArray like this
char* getCharArray(string sPhrase)
{
int size = 1;
size = sPhrase.length();
char* cArray = NULL;
cArray = new char[size+1]; // NOTE
for (int i = 0 ; i < size ; i++)
{
cArray[i] = sPhrase.at(i); // NOTE
}
}
cArray[size]=0; // NOTE
return cArray;
}
Note that the assignment in the loop now uses the index variable. Also, you need to allocate one extra char in the array to set the null terminator for the string and then you need to set it at the end.
You'll also need to think about deallocating the array at some point
The bug is in this line:
cArray[size] = sPhrase.at(i);
That size should be your loop index.
You should probably look at using std::string more, and not poke around with character arrays when there's no need to.
Why use a char array at all? It's not only useless – it complicates the code substantially (the usage of your function is more difficult, and you've forgotten to free the memory allocated by new!). Why not just have the following function:
string reverse(string const& input);
(Passing the argument by const reference instead of by value saves you a copy!)
In fact, implementing the function only takes a single line using the features of the string class (one of its constructors takes two iterators):
string reverse(string const& input) {
return string(input.rbegin(), input.rend());
}
reversePhrase is also not correct. Try something like this:
string reversePhrase(int size , char* cPhrase)
{
string sReversed = "";
sReversed.resize(size);
int place = size - 1;
for ( int i = 0; i < size ; i ++ )
{
sReversed [i] = cPhrase[place];
cout << "Current string: " << sReversed << endl;
cout << "Current character: " << cPhrase[place] << endl;
place--;
}
return sReversed;
}
First, start the array with -1. After that, use a for loop with -1 and increment inside the loop. Then, you can get the first element of the array.