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

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

Related

How do you break a long string into words and iterate through each character of word and if they match increment a char count using stringstream

int MatchString::comparsion(string newq, string oldq){
//breaks down the string into the smaller strings
stringstream s1(newq);
stringstream s2(oldq);
string new_words;
string old_words;
int word_count = 0;
while(s1>>new_words&&s2>>old_words){
for(int i = 0; i<new_words.length();i++){
for(int j = 0; j<old_words.length();j++){
char a = new_words[i];
char b = old_words[j];
if(a == b){
char_count++;
}
else{
j++;
}
}//end of 2nd for
}//end of for
}
return char_count;
}
I'm currently trying to make a function that takes in two strings and breaks them down into words then into chars. Afterward, I try to compare the value of each char and see if they equal each other. And if they do I increment a char_count by 1. Else I increment j so I compare next char in string 2 with string 1. I need to use this char_count value later to develop another algorithm because I need it to calculate a percentage difference between the two strings which is why I return it at the end because including that calculation with this method would be a bit messy. However when cout the return value I get something completely wrong. I don't know what I'm doing wrong can you please help.
Your j++ under else in the for-loop is redundant, if I'm correct. Allow your for-loop to naturally advance its iterator, don't force it within else{}.

Convert a string into a char array

New to C++ and So here is part of a project I'm working on, taking a string and printing the most commonly used number along with how many times it was used. i thought this was right, but for some reason my char array wont be read in. any tips or suggestions on how to fix?
#include <string>
#include <iostream>
using namespace std;
char getMostFreqLetter(string ss);
int main() {
string s; //initilizing a variable for string s
s = ("What is the most common letter in this string "); // giving s a string
getMostFreqLetter(s); // caling the function to print out the most freq Letter
return 0;
}
char getMostFreqLetter(string ss) {
int max, index, i = 0;
int array[255] = {0};
char letters[];
// convert all letters to lowercase to make counting letters non case sensative
for (int i = 0; i < ss.length(); i ++){
ss[i] = tolower(ss[i]);
}
//read each letter into
for (int i = 0; i < ss.length(); i ++){
++array[letters[i]];
}
//
max = array[0];
index = 0;
for (int i = 0; i < ss.length(); i ++){
if( array[i] > max)
{
max = array[i];
index = i;
}
}
return 0;
}
If you are not considering white space as letter.
Then more efficient way could have been
vector<int> count(26,0);
for (int i = 0; i < s.length(); i++) {
int range = to_lower(s[i])-'a';
if ( range >= 0 && range < 26)
count[range]++;
}
// Now you can do fix the max while iterating over count;
Use string::c_str().
It converts a string to a character array.
You have a few errors in your code.
Firstly, the array of chars letters is completely unused. You should disregard it and iterate over the string ss instead which is what I think you intended to do.
This would change your second for loop from ++array[letters[i]]; to ++array[ss[i]];.
Secondly, your last for loop is buggy. You are using i as the index to look for the frequency in array whereas you need to use the ascii value of the character (ss[i]) instead. Here is a fixed version with comments:
index = ss[0];
max = array[index];
for (int i = 0; i < ss.length(); i ++){
if(!isspace(ss[i]) && array[ss[i]] > max)
{
max = array[ss[i]]; // you intended to use the ascii values of the characters in s to mark their place in array. In you code, you use i which is the just the index of the character in s as opposed to the ascii value of that character. Hence you need to use array[ss[i]].
index = ss[i];
}
}
return index;
Once you make the above changes you get the following output when run on your string:
Most freq character: t

Loop changing a string keep failing?

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.

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.

Reading from text file into an array

I'm trying to read a textfile that I've edited with Vim into an array.
The textfile is 30*50 and is composed of single digit numbers. I've been going crazy trying to get it to work, but I think I'm having issues due to newline characters. Here's what I've been using:
Map::Map(char* filename)
{
grid[30][50] = (0);
string line;
ifstream m_file(filename);
if (m_file.is_open())
{
while(m_file.good())
{
for (int i = 0; i < 30; i++)
{
getline(m_file,line);
for (int k = 0; k < 50; k++)
{
int tnum = atoi(line.c_str());
grid[i][k] = tnum;
}
}
}
m_file.close();
}
};
grid is defined in the header file as int grid[30][50].
The code I use to print is as follows:
void display_room(int trid[30][50])
{
for (int i = 0; i < 30; i++)
{
for (int k = 0; k < 50; k++)
{
mvprintw(i,k,"%d",trid[i][k]);
};
};
};
after calling Map sMap = Map("testmap");
I'm simply trying to capture the single digit numbers into an array, and reprint that array (using curses). Currently, it reads the testmap file, and prints all zeros, no matter what is in the testmap file.
If I understand Your problem: Your parsing sets the value from the entire line where only a digit should be...
int tnum = atoi(line.c_str());
grid[i][k] = tnum;
Translating the digit (ASCII to an int/byte/... can be done in this way:
grid[i][k] = line[k] - '0';
(Perhaps some casting is needed.)
In the inner loop, you're calling atoi with the full content of the line each time. As the line is 50 character long, atoi cannot convert it to an int (the largest representable value by an int is 2147483647, and your number is probably larger than that). When atoi fails, it return 0.
What you want is convert each character of the line into an int. Something like that:
for (int i = 0; i < 30; i++)
{
getline(m_file,line);
for (int k = 0; k < 50; k++)
{
// The ASCII character of the digits 0 to 9 have
// successives values.
int tnum = line[k] - '0';
grid[i][k] = tnum;
}
}
Look at your code again. Try to see what is actually says instead of what you hope it says
int tnum = atoi(line.c_str());
You clear want that line to read each of the fifty numbers on the line in turn. But it doesn't say that. It tries to turn the whole line into an integer (and tries to do that fifty times).
Since your numbers are single digits, you actually need something much simpler
int tnum = line[k] - '0';
By saying line[k] you will get a different digit each time round the loop (because k increases each time round the loop). The - '0' bit is just a trick to turn a character into an integer. See if you can work out how it works.