Loop changing a string keep failing? - c++

cin >> n;
string disks;
for(i=0; i < n; i++){
disks[2*i] = 1;
disks[2*i+1] = 0;
}
This keeps saying: string subscript out of range. Even if I change it to (n-1). I am trying to think of a very simple way to just set this to alternating 1 and 0s and I cant find it!
Why is this loop causing an error?

When a std::string is default-constructed it's empty; you can't just start writing to it as the underlying storage hasn't been allocated.
Instead, use string disks(n * 2, '0'); to initialise the string with space for 2 * n characters. It will be pre-filled with '0' (the zeroes), then all you have to do is go through and fill in the ones.
cin >> n;
string disks(n * 2, '0');
for (int i = 0; i < n; i++)
disks[2 * i] = '1';
Also note that you need to use '0' and '1' to get the actual character values.

When you define a string that has no initial value you cannot access it, in your example with operator[]. So, the lines:
disks[2*i] = 1;
disks[2*i+1] = 0;
are causing the error, because you are trying to access an index that doesn't exist.
If you want to assign a value to a string use concatenation:
disks += "0" + "1";
or push_back(), append(). The sequence of the assigned values will determine which will be at even and odd index.

Related

Why does stoi/atoi provide me with a compiler error?

So I'm trying to convert a string (composed of a number) into digits and insert them digit by digit into a linked list.
However, when I try it I keep getting errors with the compiler.
I tried using atoi and atoi.c_str() or stoi but nothing seems to work.
string s = to_string(number_sum);
for (int i = 0; i < s.size(); i++) {
list->val = atoi(s[i].c_str);
list = list->next;
}
where list is my defined linked list, and has a int val to hold my number.
So if s = 12345, I want my linked list to be: 1->2->3->4->5.
I tried stoi(s[i]) as well, but not quite sure what the error is.
atoi and stoi convert a string into a int. You are not doing that though. What you want to do is convert a character into a int. To do that you simply subtract '0' from the character in the string to get that character as an int. That makes you code look like
string s = to_string(number_sum);
for (int i = 0; i < s.size(); i++) {
list->val = s[i] - '0';
list = list->next;
}

Having Trouble With The Reversal of a String

class Solution {
public:
string reverseWords(string s) {
int previousWhiteSpace = 0;
for(int i = 0; i <= s.size(); i ++){
if(isspace(s[i]) || i == s.size()){
for(int j = previousWhiteSpace; j < i/2; j++){
char temp = s[j];
s[j] = s[i-1-j];
s[i-1-j] = temp;
}
previousWhiteSpace = i + 1;
}
}
return s;
}
};
Hi. So the goal of my function is to reverse the input of a string. So for example, if I am given "Let's take LeetCode contest" , my function should return "s'teL ekat edoCteeL tsetnoc" . However, currently my function is ONLY returning
"s'teL take LeetCode contest" . I have a counter which I indicate as previousWhiteSpace to keep track of the start of every new word that seems to work for the first word, but not the rest. Any help would be appreciated.
You can simply assign " " to the variable previousWhiteSpace and no need to increment. thus your code will detect white space automatically till the end of the string and will run the code after every white space. As you have assigned value 0 to it will only perform the result for the first word and it will terminate.

C++ Add random characters into a string array

So I want to create 1000 words with a length of 5 random characters. In my main I have word[1000] but when I try to run this code, it gives me an error saying "Expression:string subscript out of range". I'm not sure why it does that because I thought string arrays were 2 dimensional? If anyone could tell me why my code is wrong I'd appreciate it. Thanks.
void createText(string w[], int seed) {
char ch;
srand(seed);
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 5; j++) {
ch = ('A' + rand() % 26);
w[i][j] = ch;
}
}
for(int i = 0; i < 1000; i++) {
cout << w[i];
}
cout << endl;
}
I suppose that the array w does not have 1000 elements, also remember that here you will get a copy of string w[]. Better would be passing a pointer to w (string* w), then You will have very clearly what is wrong. remember also that cout writes the string out untill it reaches a '\0' character, this also might be the cause. Quick session with gdb will help:
gdb program
...
run
bt full
should pinpoint Your problem. if it's some kind of IDE, learn how to debug in it. Valgrind or some other memcheck like visual leak detector or luke stackwalker will also show you some tips about bad initialization or unmentioned memory leaks.
If an array is bidimensional, you can't print its values like w[i]. You must print always keeping in mind that the array is bidimensional, which means that the output must be done like cout << w[i][j];
In addition, you're passing an array of strings as an argument, and what you're doing is add characters to every single position, which means that you won't actually have nothing but 1000 characters inserted into that string (because you actually added "one-char" strings), so you'll only put 200 words with a length of 5 characters each one. Insert strings directly, and you'll get your 1000 words, but first find a way to build strings with random characters.
Something like:
for(conditions){
for(conditions){
build a word
}
array[x][y] = string
}
I guess it is similar to what you intended to do

How to generate a set of unique hash strings in C++?

This code produce 26*26*26*26 hasname (using combinations of a-z)or you can say random names which i want to assign to a structure member.Now when i am assigning that by first allocating that structure member sufficient memory and then using strcpy, only last hashname generated by this code is being passed to the structure i.e zzzz(it is the last hashname).What can i do so that hashname is assigned from the starting.
vcd_xyz[4] = '\0';
int count = 0;
for(int i=0;i<26;i++)
{
vcd_xyz[0] = 'a'+i;
for(int j=0;j<26;j++)
{
vcd_xyz[1] = 'a'+j;
for(int k = 0;k<26;k++)
{
vcd_xyz[2] = 'a' + k;
for(int l=0;l<26;l++)
{
vcd_xyz[3] = 'a' +l;
count ++;
printf("%s\n",vcd_xyz);
}
}
}
}
So i am using
sss->Variables[0].hashname = (char*)calloc(strlen((char*)vcd_xyz)+1,sizeof(char));
strcpy(sss->Variables[0].hashname,(char*)vcd_xyz);
to copy the hasname produced but it is copying the last hashname produced, so where ever i am using tr0->Variables[0].hashname = (char*)calloc(strlen((char*)vcd_xyz)+1,sizeof(char));
strcpy(tr0->Variables[0].hashname,(char*)vcd_xyz); only zzzz get printed.what i am doing wrong or what should i do so that hashname are assigned in a sequential manner.
At first you need to realize that char vcd_xyz[4] is an array of 4 characters, meaning that you can put there 3 characters + terminating character '\0'. If you treat this array as it is null-terminated when it is not, it results in undefined behavior.
What your code actually does is that it iterates through all possible combinations of 4 letters long strings, from "aaaa" to "zzzz", leaving the vcd_xyz array filled with the last combination (i.e. "zzzz").
If you want to generate random 4-letters long string, here's the C-style function you might use:
int irand(int min, int max) {
return ((double)rand() / ((double)RAND_MAX + 1.0)) * (max - min + 1) + min;
}
it generates random number from <min;max> interval and it can be used like this:
std::string generateHashTag() {
char str[5];
for (int i = 0; i < 4; ++i)
str[i] = irand('a', 'z');
str[4] = '\0';
return std::string(str);
}
But in case you want to generate a set of unique 4-letters long hash tags, you will need more complex solution. In C++ you might easily generate these strings in a loop that will put them into an std::set container till you have enough of them or you might generate more unique combinations of this string, put all of these into an std::vector, shuffle it and pick first N, e.g.:
const size_t N = 5;
std::set<std::string> myHashTags;
srand(time(0));
while (myHashTags.size() < N)
myHashTags.insert(generateHashTag());
for (std::set<std::string>::iterator i = myHashTags.begin();
i != myHashTags.end(); ++i)
std::cout << *i << ' ';
outputs kemy snwv vnmi wfmm wqeg. Full example here.

std::string Array Element Access

Despite being a Project Euler program, the following code doesn't actually concern it much. I want to add 50 100-digit numbers, and I'm assigning each digit of each number to an element in the array addends[100][50]. I'd then add up each digit/place individually, and carry over extra digits. The numbers are being read in from a text file named Input.txt, and it merely contains all the numbers. http://projecteuler.net/problem=13
I'm having trouble assigning characters to elements of a string array (string numbers[100][50]) from a file input stream (<fstream>). The problem is described more completely in the comments:
"[for the 1st loop] This loop assigns a number to every string in the string array. Even though the second number (50) doesn't do anything (it seems to be overridden by std::string; see variable declaration), it needs to be there for the loop to work. Same "logic" for the loop; "j" doesn't do anything but needs to be there for the loop to work?"
And also, (for the 2nd loop) "This loop fills in the "addends[100][50]" array from the corresponding string array element. If I try to call "char_to_int()" with the array"numbers[i][j]", the compiler complains that the input isn't of the right data type. Adding a variable "k" makes the loop work for one run, but eventually crashes on the second loop (using "numbers[i][j][k]"). So I tried "char_to_int((numbers[i][j]).c_str())", but the compiler complains that "const char *" is incompatible with "char". Adding a pointer resolves the issue ("char_to_int( *( (numbers[i][j]).c_str() ) )"), but the program still crashes later." I took out some code that doesn't matter to make it more readable.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int char_to_int(char chInput);
int main()
{
int placeholder; //so console doesn't close immediately upon finish
int sum[102] = {0}; // 100+2, 100 places + 2 places from carrying over
int addends[100][50] = {0};
string numbers[100][50];
ifstream input("Input.txt");
/* This loop assigns a number to every string in the string array. Even
* though the second number (50) doesn't do anything (it seems to be
* overridden by std::string; see variable declaration), it needs to be
* there for the loop to work. Same "logic" for the loop; "j" doesn't do
* anything but needs to be there??? Confused :-\
*/
for (int i = 0; i < 100; i++)
for (int j = 0; j < 1; j++)
getline(input, numbers[i][j]);
/* This loop fills in the "addends[100][50]" array from the corresponding
* string array element. If I try to call "char_to_int()" with the array
* "numbers[i][j]", the compliler complains that the input isn't of the
* right data type. Adding a variable "k" makes the loop work for one run,
* but eventually crashes on the second loop (using "numbers[i][j][k]").
* So I tried "char_to_int((numbers[i][j]).c_str())", but the compiler
* complains that "const char *" is incompatible with "char". Adding a
* pointer resolves the issue ("char_to_int( *( (numbers[i][j]).c_str() ) )"),
* but the program still crashes on the second loop through.
*/
for (int i = 0; i < 100; i++)
for (int j = 0; j < 50; j++)
for (int k = 0; k < 1; k++) //used when the variable "k" was being used
addends[i][j] = char_to_int( (numbers[i][j]).c_str() );
return 0;
}
The code isn't finished; I decided against going on since I (obviously) need to fix this first.
It compiles and runs fine with
string numbers[100];
for (int i = 0; i < 100; i++)
getline(input, numbers[i]);
for (int i = 0; i < 100; i++)
for (int j = 0; j < 50; j++)
addends[i][j] = char_to_int( (numbers[i][j]));
after removing the stdafx.h include and defining char_to_int.
A std::string contains an array of characters itself, so you only need a one-dimensional array of std::strings. You can then access the characters of a string by [] indexing,
numbers[i][j]
gets the j-th character (byte, rather) of the i-th string in the array numbers.