Basically I just need to fill the string with all the letters from the vector. The vector is of type char, but it shouldn't matter right? When I debugged it, it said the size of string was still 0? Here's a snippet of code.
NOTE: Vector size is 7 (tested in output) so the problem doesn't seem to lie in the vector.
vector<char> final; //note this gets filled before reaching the loop
// fills vector in here, size is now 7
string* complete;
complete = new string[final.size()]; //set size of string to vector size
//debugger says size of complete is 0????
for (int i = 0; i < final.size(); i++) {
complete[i] = final[i]; //should fill string
}
cout << "COMPLETE:" << *complete << endl; //one letter output
Here's a one-liner to do it:
string complete(final.begin(), final.end());
or:
string complete(final.data(), final.size());
Related
I have a very simple structure for adding size field to dynamic arrays:
template <typename T>
struct sized_array {
int size;
T* array;
};
I cannot use std::vector or std::array. The function to fill the array initializes the sized_array.array field and fills it with random integers:
void array_fill(sized_array<int> &array, int size = ARRAY_SIZE) {
array.array = new int[size];
array.size = size;
for (int i = 0; i < size; i++) {
array.array[i] = random_in_range(RANDOM_MIN, RANDOM_MAX);
}
}
The other functions, array_join and array_print print the contents of an array:
string array_join(sized_array<int> &array, string delimiter) {
string text = "";
for (int i = 0; i < array.size; i++) {
text += array.array[i];
if (i < array.size) text += delimiter;
}
return text;
}
void array_print(sized_array<int> &array) {
cout << "array(" << array.size << ") = [";
cout << array_join(array, ", ") << "]" << endl;
}
The array variable is declared like so, and the program runs this code:
sized_array<int> number_array;
int main() {
srand(time(NULL));
array_fill(number_array);
array_print(number_array);
system("pause");
return 0;
}
When debugging, the array shows this value when first initialized, then appears to take the first returned value of random_in_range and never change, staying at one element -- the first returned value.
When printed, the array appears to be filled with random ASCII characters, and the first element is never the one it was (even though the debugger displayed it had one element).
What is the cause of this and how to avoid this problem?
When printed, the array appears to be filled with random ASCII characters
This is because you have an error in your array_join function:
text += array.array[i];
This would append an int re-interpreted as char, not a decimal representation of the number.
Use std::to_string to fix the problem:
text += std::to_string(array.array[i]);
If you are restricted to a C++ version prior to C++11, use std::stringstream instead.
So I found this code on the internet, but as I'm not that familiar with C++. I found difficult to understand this: how does a vector suddenly becomes a matrix?
int main(){
int n;
string v[MAX];
cin >> n;
for(int i=0;i<n;i++)
cin >> v[i];
for(int i=0;i<n-1;i++){
int y1,y2;
y1=v[i].size();
y2=v[i+1].size();
for(int j=0; j<y1 && j<y2 ;j++)
if(v[i][j]!=v[i+1][j]){ // here <-
int x1,x2;
x1=(int) v[i][j]-'A';
x2=(int) v[i+1][j] - 'A';
m[x1][0]=true;
m[x2][0]=true;
m[x1][x2+1]=true;
break;
}
}
string v[MAX];
is an array of std::string (presumably - this is one reason to avoid using namespace std;. How do I know what type of string it is?).
You can access elements of an array with []:
int someInts[5];
someInts[3]=1000; // sets the 4th int (counting starts from 0)
You can also access characters in a std::string with []:
std::string name("chris");
std::cout << name[3]; // prints 'i'
So you can access the letters in an array of std::strings with two sets of []:
std::string names[10]; // 10 names
names[3] = "chris"; // set the 4th name
std::cout << names[3][1]; // prints 'h'
// ^ access letter in string
// ^ access string in array
Here is a self-explanatory example
int main()
{
std::string name;
name = "test";
for(int i = 0; i<4; i++)
std::cout<<name[i]<<std::endl;
std::cout << "Hello, " << name << "!\n";
}
It will print
t
e
s
t
Hello, test!
So, an array of strings is actually a 2D array of characters, that you called a matrix.
string v[N] is an array of string, string itself is an array of chars.
Since, as the commentor pointed out, there are neither vectors or matrices in the code you gave, I'll make a couple assumptions:
By "vector", you mean "array"
You think that double square brace operators ([][]) indicate a matrix.
If those are both true, I can explain what you're seeing:
string[5] strings = { Some Strings... }
//The first string in the array
string string1 = strings[0];
//The first letter of the first string
char char1 = string1[0];
//The above is the same as:
char char1Again = strings[0][0];
In the line above, the first square bracket operator returns the first string in the array. The second square bracket operator is then applied to that string, which returns the first character of that string.
This works because both arrays and Strings (which are really arrays themselves deep down) implement the square bracket operator to access their internal elements by index.
Technically, in a convoluted way, you could call this a matrix, but "2D array of characters" would be more appropriate.
Here is the code for adding vertex to a graph:
void myGraph::addVertex(const string &newVertex)
{
if (getIndex(newVertex) != -1)
{
std::cout << ("addVertex: ");
std::cout << newVertex;
std::cout << (" failed -- vertex already exists.") << std::endl;
return;
}
// if array of vertices is full, we need to expand it and
// also expand Edges
if (sizeof(Vertices)/sizeof(Vertices[0])==numVertices)
{
Vertices = resize(Vertices, 2*numVertices + 1);
Edges = resize(Edges, 2*numVertices + 1);
}
Vertices[numVertices++] = newVertex;
}
and here is the code for resizing of Vertices array:
string *myGraph::resize(string array1[], int newSize)
{
// make array of size equal to new size
string *temp = new string [newSize];
int smallerSize = newSize;
// if the size of input array is less than the new size then smaller size will be that of input array
if (sizeof(array1)/sizeof(array1[0]) < smallerSize)
{
smallerSize = sizeof(array1) / sizeof(array1[0]);
}
// loop till smaller size and copy the content of input array to newly created array
for (int i = 0; i < smallerSize; i++)
{
temp[i] = array1[i];
}
return temp;
}
When I debug this code, it adds only 1 vertice, i.e. numVertices=1 and on next step it says in Vertices[numVertices++]
sizeof is giving the size of the pointer to the data in your array, not the total size of the array. It depends on your platform, but it is very likely that sizeof(string*)/sizeof(string) (equivalent to your size calculation) is always going to return 1. You should probably be using something like std::vector or std::list for this, the right choice depends on how exactly you will be using it. These standard container classes will handle allocating memory and resizing for you, so you don't have to worry about it.
You can fix it by passing old array size to resize:
string *myGraph::resize(string array1[], int array1Size, int newSize)
then:
if (array1Size < smallerSize) {
smallerSize = array1Size ;
}
as Katie explains, sizeof(array1) in your code is not the size of the actual array, you should rather use string* array1 to make clear that it is pointer to allocated memory on heap
I am writing a C++ function that is supposed to duplicate an array of chars by copying each element character-by-character into a new array. Ideally, if I make the statements
char* a = "test";
char* b = copyString(a);
then both a and b should contain the string "test." However, when I print the copied array b, I get "test" plus a series of nonsense characters that seem to be the pointer. I don't want those, but I can't figure out where I'm going wrong.
My current function is as follows:
char* copyString(char* s)
{
//Find the length of the array.
int n = stringLength(s);
//The stringLength function simply calculates the length of
//the char* array parameter.
//For each character that is not '\0', copy it into a new array.
char* duplicate = new char[n];
for (int j = 0; j < n; j++)
{
duplicate[j] = s[j];
//Optional print statement for debugging.
cout << duplicate[j] << endl;
}
//Return the new array.
return duplicate;
}
For the purposes of understanding certain aspects of C++, I cannot use string libraries, which is where other answers I have found have fallen short in this case. Any help with this problem is greatly appreciated.
EDIT: I though my stringLength function was fine - perhaps I was wrong.
int stringLength(char* s)
{
int n;
//Loop through each character in the array until the '\0' symbol is found. Calculate the length of the array.
for (int i = 0; s[i] != '\0'; i++)
{
n = i + 1;
}
//Optional print statement for debugging.
// cout << "The length of string " << s << " is " << n << " characters." << endl;
return n;
}
You need to copy the 0 too. That's what a C-style string is, a null-terminated character array.
Really, all you need to do is add one to the length:
int n = stringLength(s) + 1; // include the '\0'
And then everything else will account for itself - you'll allocate an array of sufficient size, and copy the '\0' in your loop too.
#include <iostream>
using namespace std;
int main()
{
cout << "Do you need to encrypt or decrypt?" << endl;
string message;
getline(cin, message);
int letter2number;
for (int place = 1; place < sizeof(message); place++)
{
letter2number = static_cast<int>(message[place]);
cout << letter2number << endl;
}
}
Examples of problem: I type fifteen letters but only four integers are printed. I type seven letters but only four integers are printed.
The loop only occurs four times on my computer, not the number of characters in the string.
This is the only problem I am having with it, so if you see other errors, please don't tell me. (It is more fun that way.)
Thank you for your time.
sizeof returns the size of an expression. For you, that's a std::string and for your implementation of std::string, that's four. (Probably a pointer to the buffer, internally.)
But you see, that buffer is only pointed to by the string, it has no effect on the size of the std::string itself. You want message.size() for that, which gives you the size of the string being pointed to by that buffer pointer.
As the string's contents change, what that buffer pointer points to changes, but the pointer itself is always the same size.
Consider the following:
struct foo
{
int bar;
};
At this point, sizeof(foo) is known; it's a compile-time constant. It's the size of an int along with any additional padding the compiler might add.
You can let bar take on any value you want, and the size stays the same because what bar's value is has nothing to do with the type and size of bar itself.
You want to use message.size() not sizeof(message).
sizeof just gives the number of bytes in the data type or expression. You want the number of characters stored in the string which is given by calling size()
Also indexing starts at 0, notice I changed from 1 to 0 below.
for (int place = 0; place < message.size(); place++)
{
letter2number = static_cast<int>(message[place]);
cout << letter2number << endl;
}
Any pointer on an x86 system is only 4 bytes. Even if it is pointing to the first element of an array on the heap which contains 100 elements.
Example:
char * p = new char[5000];
assert(sizeof(p) == 4);
Wrapping p in a class or struct will give you the same result assuming no padding.
class string
{
char * ptr;
//...
size_t size(); // return number of chars (until null) in buffer pointed to by ptr
};
sizeof(message) == sizeof(string) == sizeof(ptr) == 4; // size of the struct
message.size() == number of characters in the message...
sizeof(type) returns the size of the type, not the object. Use the length() method to find the length of the string.
#include<iostream>
#include<conio.h>
using namespace std;
int main()
{
cout << "Do you need to encrypt or decrypt?" << endl;
string message;
getline(cin, message);
int letter2number;
for (int place = 0; place < message.size(); place++)
{
letter2number = static_cast<int>(message[place]);
cout << letter2number << endl;
}
getch();
return 0;
}