Trouble copying the string using memcpy - c++

I have a string say toioyhpknmtlghk.I want to create a 2-d character array having n rows such that it contains first,second,third sub strings of length n as it's rows.
For example,here n=5 the sub strings of length 5 are, toioy hpknm and tlghk
so array arr should look like
t o i o y
h p k n m
t l g h k
Now this could have been easier if I copy the characters by looping through the array but here I am trying to use memcpy as,
int main()
{
long n;
cin>>n;
char a[3][n+1];char str[20]; //I have taken n+1 columns as n for substring and 1 for '\0'
scanf("%s",str);
char *p=str;
memcpy(a[0],p,n);strcat(a[0],"\0");
p=p+n;
memcpy(a[1],p,n);strcat(a[1],"\0");
p=p+n;
memcpy(a[2],p,n);strcat(a[2],"\0");
for(int i=0;i<3;i++)
{
printf("%s\n",a[i]);
}
}
But on outputting the array following results are obtained,
//input
5
toioyhpknmtlghk
//output
toioy
hpknm{tlghk‼â
tlghk‼â

The command strcat(a[0],"\0"); is working on strings which are already terminated by \0. Otherwise it doesn't know where to append the second string. In your case a[0] is not terminated, so the function will induce undefined behavior. You can do the following instead:
a[0][n] = '\0';
(the same is for the rest of a elements)

Related

Input Different Length Stings in c++?

I want to take different length strings without knowing their length and distributing their characters in arrays as input in c++.
Take number of strings (3)
Take first string. Example: hello and it should be saved like
a[]={'h','e','l','l','o'}
Take second string
Take third string
To store the characters of a string in an array, you could try this:
string string1 = "Hello";
char a[string1.length()+1];
for (int i = 0; i < string1.length(); i++)
{
a[i] = string1[i];
}
That will loop through the entire string and by using .length(), store the indexed values in a[]. If you have several strings, just repeat the process.

Does anyone know how to solve problems on variable length arrays?

Input Format
The first line contains two space-separated integers denoting the respective values of (the number of variable-length arrays) and (the number of queries).
Each line of the subsequent lines contains a space-separated sequence in the format k a[i]0 a[i]1 … a[i]k-1 describing the -element array located at.
Each of the subsequent lines contains two space-separated integers describing the respective values of (an index in the array ) and (an index in the array referenced by ) for a query.
Output Format-
For each pair of and values (i.e., for each query), print a single integer denoting the element located at an index of the array referenced by. There should be a total of lines of output.
Sample Input
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
Sample Output
5
9
Somebody has solved this problem by -
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int n,q; //n number of variable lenght arrays
// q no of queries asked
cin >>n >>q;
int ** Vectors = new int *[n];//no of length of var. arrays
int j;
for (int i=0;i<n;i++)
{
cin>>j;
Vectors[i] = new int [j];
for (int y=0;y<j;y++)
cin>>Vectors[i][y];
}
int q1,q2;
for (int i=0;i<q;i++)
{
cin >>q1 >> q2;
cout<<Vectors[q1][q2]<<endl;
}
return 0;
}
Can somebody explain me this code? Or if anyone has a better approach to solve this problem. Then please explain it in detail.
This shouldn't be hard to understand, that code is basically initializing dynamic 2D array at run time then inserting values to the 2D array and then accessing it by giving index:
int ** Vectors = new int *[n];//no of length of var. arrays
int j;
for (int i=0;i<n;i++)
{
cin>>j;
Vectors[i] = new int [j]; // initialzing inner array.. consider it as 2D array with n rows and j columns
for (int y=0;y<j;y++)
cin>>Vectors[i][y]; // insert element at specified index
}
cout<<Vectors[q1][q2]<<endl; // access element from 2D array
What you might want to use is a Matrix class.
Using
vector<vector<int>>
should do it.
Alternatively the snipet code should be refactored into a Matrix class with a constructor and a destructor.
The example you give present a memory leak since the allocated memory is not freed.

Not getting the input values when printing vector of pairs

I want to add a pair to a vector of pairs.
When I print the vector elements, I don't get the integers I input.
Please help.
#include<iostream>
#include<vector>
#include<utility>
using namespace std;
int main()
{
vector<vector<unsigned long int> >matrix;
vector<pair<int,int> >pmat;
int L;
cin>>L;
int n1, n2;
pmat.resize(L);
for(int k = 0; k<L; k++)
{
cin>>n1>>n2;
pair<int,int> p = make_pair(n1,n2);
cout<<p.first<<p.second<<endl;
pmat.push_back(p);
}
for(int k = 0; k<L; k++)
{
cout<<pmat[k].first<<','<<pmat[k].second<<' ';
}
cout<<endl;
return 0;
}
Method 1:
Delete this line:
pmat.resize(L);
You don't need to resize it in the first place as you do push_back() when adding afterwards.
Method 2:
Change the following line
pmat.push_back(p);
to
pmat[k] = p;
You can do resize() in the first place, but after this, you should not use push_back() when adding, just use pmat[k] = p.
PS: you should not mix these two ways up. Always use one of them consistently.
Since you're using pmat.resize(L) and L times pmat.push_back(...), you're ending up having stored 2 * L entries in your vector. However you're printing just the first half, index 0 to L - 1. The values you want are stored from index L to 2 * L - 1.
Just change pmat.resize(L) to pmat.reserve(L).
Alternatively, you can use the resize(L), but to end up with L entries, you need to store each input pair to pmat[k], hence you write pmat[k] = p;.
As a rule of thumb, I recommend using the reserve + push_back approach if you know how many elements you're going to add. The reason is, that resize initializes the elements, while reserving just asserts that there will be enough space and no reallocation will be necessary with any following push_back.
You don't want to add more pairs after you allocated them. You can now directly access them.
Just use pmat[k] = p; instead of pmat.push_back(p);
If you print the size of the vector after reading the values, you will notice a small problem with your program:
./test
2
1 2
12
3 4
34
Size of the vector: 4
0,0 0,0
Huh? Even though I only entered 2 pairs, the size of the vector is 4. How did this happen?
If you look at the documentation for resize, it says
Resizes the container to contain count elements.
So even before you read any values, your vector will already contain 2 elements! Those will be default-constructed and therefore be 0. When you then push_pack the elements you read in, those will land at the indices 2 and 3 in the vector, so the end vector has twice as much elements as you wanted (4 in this case). You only print out the first half, which are the zero values.
The solution is to use reserve instead of resize, which doesn't create the elements but only reserves space for them, or just delete the call to resize. Using reserve is more efficient though, because then the vector will only need to allocate memory once.
pmat.resize(L);
if vector in empty its going to initialize a vector pmat with size L then assign default values to vector so now pmat size is L with default values
for(int k = 0; k<L; k++)
{
cin>>n1>>n2;
pair<int,int> p = make_pair(n1,n2);
cout<<p.first<<p.second<<endl;
pmat.push_back(p);
}
then u r pushing values to pmat L times so the final size is 2*L
for(int k = 0; k<L; k++)
{
cout<<pmat[k].first<<','<<pmat[k].second<<' ';
}
here u r going to read from 0 to L-1 , it contains default values you can see your values from L-1 to 2L-1.
so finally what i want say is use reserve instead of resize
or
pmat.resize(L); comment this line

Comparisons of strings with c++

I used to have some code in C++ which stores strings as a series of characters in a character matrix (a string is a row). The classes Character matrix and LogicalVector are provided by Rcpp.h:
LogicalVector unq_mat( CharacterMatrix x ){
int nc = x.ncol() ; // Get the number of columns in the matrix.
LogicalVector out(nc); // Make a logical (bool) vector of the same length.
// For every col in the matrix, assess whether the column contains more than one unique character.
for( int i=0; i < nc; i++ ) {
out[i] = unique( x(_,i) ).size() != 1 ;
}
return out;
}
The logical vector identifies which columns contain more than one unique character. This is then passed back to the R language and used to manipulate a matrix. This is a very R way of thinking of doing this. However I'm interested in developing my thinking in C++, I'd like to write something that achieves the above: So finds out which characters in n strings are not all the same, but preferably using the stl classes like std::string. As a conceptual example given three strings:
A = "Hello", B = "Heleo", C = "Hidey". The code would point out that positions/characters 2,3,4,5 are not one value, but position/character 1 (the 'H') is the same in all strings (i.e. there is only one unique value). I have something below that I thought worked:
std::vector<int> StringsCompare(std::vector<string>& stringVector) {
std::vector<int> informative;
for (int i = 0; i < stringVector[0].size()-1; i++) {
for (int n = 1; n < stringVector.size()-1; n++) {
if (stringVector[n][i] != stringVector[n-1][i]) {
informative.push_back(i);
break;
}
}
}
return informative;
}
It's supposed to go through every character position (0 to size of string-1) with the outer loop, and with the inner loop, see if the character in string n is not the same as the character in string n-1. In cases where the character is all the same, for example the H in my hello example above, this will never be true. For cases where the characters in the strings are different the inter loops if statement will be satisfied, the character position recorded, and the inner loop broken out of. I then get a vector out containing the indicies of the characters in the n strings where the characters are not all identical. However these two functions give me different answers. How else can I go through n strings char by char and check they are not all identical?
Thanks,
Ben.
I expected #doctorlove to provide an answer. I'll enter one here in case he does not.
To iterate through all of the elements of a string or vector by index, you want i from 0 to size()-1. for (int i=0; i<str.size(); i++) stops just short of size, i.e., stops at size()-1. So remove the -1's.
Second, C++ arrays are 0-based, so you must adjust (by adding 1 to the value that is pushed into the vector).
std::vector<int> StringsCompare(std::vector<std::string>& stringVector) {
std::vector<int> informative;
for (int i = 0; i < stringVector[0].size(); i++) {
for (int n = 1; n < stringVector.size(); n++) {
if (stringVector[n][i] != stringVector[n-1][i]) {
informative.push_back(i+1);
break;
}
}
}
return informative;
}
A few things to note about this code:
The function should take a const reference to vector, as the input vector is not modified. Not really a problem here, but for various reasons, it's a good idea to declare unmodified input references as const.
This assumes that all the strings are at least as long as the first. If that doesn't hold, the behavior of the code is undefined. For "production" code, you should include a check for the length prior to extracting the ith element of each string.

count number of times a character appears in an array?

i've been thinking for a long time and havent got anywhere with the program. i dont know where to begin. The assignment requires use of single function main and only iostream library to be used.
the task is to Declare a char array of 10 elements. Take input from user. Determine if array contains any values more than 1 times . do not show the characters that appears 1 time only.
Sample output:
a 2
b 4
..
a an b are characters. and 2 and 4 represents number of times they appear in the array B.
i tried to use nested loop to compare a character with all the character in array and incrementing a counter each time similer character id sound but unexpected results are occuring.
Here is the code
#include <iostream>
using namespace std;
void main()
{
char ara[10];
int counter=0;
cout<<"Enter 10 characters in an array\n";
for ( int a=0; a<10; a++)
cin>>ara[a];
for(int i=0; i<10; i++)
{
for(int j=i+1; j<10; j++)
{
if(ara[i] == ara[j])
{
counter++;
cout<<ara[i]<<"\t"<<counter<<endl;
}
}
}
}
Algorithm 2: std::map
Declare / define the container:
std::map<char, unsigned int> frequency;
Open the file
read a letter.
find the letter: frequency.find(letter)
If letter exists, increment the frequency: frequency[letter]++;
If letter no exists, insert into frequency: frequency[letter] = 1;
After all letters processed, iterate through the map displaying the letter and its frequency.
Here's one possible way you can solve this. I'm not giving you full code; it's considered bad to just give full implementations for other people's homework.
First, fill a new array with only unique characters. For example, if the input was:
abacdadeff
The new array should only have:
abcdef
That is, every character should appear only once in it. Do not forget to \0-terminate it, so that you can tell where it ends (since it can have a length smaller than 10).
Then create a new array of int (or unsigned, since you can't have negative occurrences) values that holds the frequency of occurence of every character from the unique array in the original input array. Every value should be initially 1. You can achieve this with a declaration like:
unsigned freq[10] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
Now, iterate over the unique array and every time you find the current character in the original input array, increment the corresponding element of the frequencies array. So at the end, for the above input, you would have:
a b c d e f (unique array)
3 1 1 2 1 2 (frequencies array)
And you're done. You can now tell how many times each characters appears in the input.
Here, I'll tell you what you should do and you code it yourself:
include headers ( stdio libs )
define main ( entry point for your app )
declare input array A[amount_of_chars_in_your_input]
write output requesting user to input
collect input
now the main part:
declare another array of unsigned shorts B[]
declare counter int i = 0
declare counter int j = 0
loop through the array A[] ( in other words i < sizeof ( A ); or a[i] != '\0' )
now loop as much as there is different letters in the array A
store the amount of letters in the B[]
print it out
Now there are some tricks applying this but you can handle it
Try this:
unsigned int frequency[26] = {0};
char letters[10];
Algorithm:
Open file / read a letter.
Search for the letters array for the new letter.
If the new letter exists: increment the frequency slot for that
letter: frequency[toupper(new_letter) - 'A']++;
If the new letter is missing, add to array and set frequency to 1.
After all letters are processed, print out the frequency array:
`cout << 'A' + index << ": " << frequency[index] << endl;