this question should be easy and straight forward, but after searching online, I couldn't find an answer. might because the question is just too simple.
following code is from cplusplus.com. it's a function of making a string lowercase. I was intended to do something similar.
/* tolower example */
#include <stdio.h>
#include <ctype.h>
int main ()
{
int i=0;
char str[]="Test String.\n";
char c;
while (str[i])
{
c=str[i];
putchar (tolower(c));
i++;
}
return 0;
}
and what I made is this:
void search(string A[], string B[], int k)
{
int temp;
for(int j = 0; j <= 4; j++)
{
for(int i = 0; i <= k; i++)
{
string str (A[i]);
int h = 0;
char lstr[] = B[j];
char c;
while (lstr[h])
{
c = lstr[h];
putchar (tolower(c));
h++;
}
string key (B[j]);
.....
this part of the code is in a for loop. B[j] is a string array.
Visual Studio informed me that char lstr[] = B[j]; part is not right, the error message is:
Error: initialization with '{...}' expected for aggregate object.
I think the problem is that I didn't use the correct syntax of using a string array in a function. something should be done for B[j], in order to make it a char array. I couldn't figure it out.
is that something about pointer? sorry I haven't learn pointer yet.
does my question make sense for you? any help is greatly appreciated!!
If you're looking to make the letters in the string lowercase it's more readable to just work with strings all the way and use std::transform. For example,
// make sure to #include <algorithm>
// at the top
string lstr = B[j];
std::transform(lstr.begin(), lstr.end(), lstr.begin(), ::tolower);
This is much more natural and c++ idiomatic than working with char * directly and less error-prone.
You're trying to assign a char to char[]. You can get the effect you want with the following code:
....
int h = 0;
char* lstr = &B[j]; // point lstr to the address of j'th element of B.
char c;
while (lstr[h])
{
c = lstr[h];
putchar (tolower(c));
h++;
}
.....
What this does is that lstr is now a pointer that points to the j'th character in B. Arrays are essentially pointers. When you do B[j], it's equivalent to writing char ch = *(B + j);, where B points to the address of the first character in the array of characters (otherwise known as string).
EDIT
After your edit, it now seems that you're trying to assign a std::string to a char. Here is the corrected solution.
....
int h = 0;
string& lstr = B[j]; // grab a reference to the j'th string in B.
char c;
while (lstr[h])
{
c = lstr[h];
putchar (tolower(c));
h++;
}
.....
Here, lstr is essentially a reference to the j'th string in B and you can use it as a regular string just like how you're using string str(A[i]);, which makes a copy of the i'th string in A.
You're confusing character arrays and string objects here. A character array is an array of bytes of set size which is null terminated, while a string is an object which expands/contracts as is necessary and doesn't require the null terminator. You're attempting to assign a string object to a character array, which is unsupported. If you're working with string objects, and want to retrieve their equivalent character array, utilize the c_str() function:
const char* lstr = B[j].c_str()
Also, utilizing an array name of B and an index of j is hilarious.
Related
I tried to reverse a string using char array but in the output it prints some garbage value, I am unaware of that what is the cause plus it is only happening in large strings.
my code
string reverseWord(string str){
int j = 0, n=0;
n = str.length();
char t[n]={0};
for(int i=n-1;i>=0;i--)
{
t[j]=str[i];
j+=1;
}
return t;
}
input = APFGMRZXIFPSXKOQDRRQJBBZ
output = ZBBJQRRDQOKXSPFIXZRMGFPAB#
I want to know the reason behind # these two garbage values
Using online IDE of gfg.
C-style strings must be terminated by a null-character '\0'.
Instead of using Variable-Length Array, which is not in the standard C++, you should directly allocate string because you are returning that. (assuming that string here means std::string)
string reverseWord(string str){
int j = 0, n=0;
n = str.length();
string t(n); // allocate string instead of VLA
for(int i=n-1;i>=0;i--)
{
t[j]=str[i];
j+=1;
}
return t;
}
Basically, here, I'm trying to reverse an array, and convert the reversed int array into a string (I'm trying to write the equivalent of Java's BigInteger class in C++ - basically turning the input into big endian ordering, breaking down the operations, reversing the result back to little endian format, and returning the string).
And as you can see below, it outputs some strange characters (I think it's an out of range reference?) - but I'm not entirely sure what caused this output?
I would really appreciate if you could take a look at it:
Sample input
int a[] = {1, 2, 3};
int rA[3];
reverseIntArray(a, rA, 3);
string aString = intArrayToString(a, 3);
cout << aString << endl;
Console output
123\216\377
As you can see - it calculates the answer correctly, with the exception of the \277_\377.
I'll post the rest of the relevant functions:
reverseIntArray
void reverseIntArray(int array[], int reversedArray[], int arrayLength) {
for (int i = 0; i < arrayLength; i++) {
reversedArray[i] = array[arrayLength - 1 - i];
}
}
intArrayToString
string intArrayToString(int digits[], int length) {
// convert int array to char array
char digitsChar[length];
for (int i = 0; i < length; i++) {
digitsChar[i] = '0' + digits[i];
}
// convert char array to string
string intString(digitsChar);
return intString;
}
I'm quite sure this is a subtle issue to do with pointers, but I'm still relatively new to C++ (migrating from Java) and I've stared at this for hours but haven't come up with any ideas.
The std::string constructor you are using is assuming that the string you pass is properly terminated, which it isn't and that leads to undefined behavior as the std::string constructor goes beyond the end of the digitsChar array.
Three possible solutions:
Make room for another character in the digitsChar array and terminate it:
char digitsChar[size + 1];
for (...) { ... }
digitsChar[3] = '\0';
string intString(digitsChar);
Use another constructor where you pass the length of the character array:
string intString(digitsChar, length);
Append the characters directly to the string:
string intString;
for (int i = 0; i < length; i++) {
intString += '0' + digits[i];
}
There are of course other solutions as well, like for example using std::ostringstream.
so I'm working on a project that I have to read contents from a file and then analyze them. But I'm having a problem with getting the string out of a pointer that contains the address to what I need.
string lePapel(vector<char> vec){
string *str, s;
int i, j = 0;
vector<char> aux;
aux.resize(6);
for (i = 57; i <= 62; i++){
aux[j] = vec[i];
j++;
}
str = new string[aux.size()];
for (i = 0; i < 6; i++){ str[i] = aux[i]; }
return s;
}
So, the file contains in the array positions from 57 to 62 the word: ABCB4, but when returning the string s my output is A only as expected because of the pointer.
The thing is that I have been trying to find a solution and storing the whole content from vec[57] to vec[64] into the string s and returning it, and the closest that I got to returning anything plausible was using a pointer.
So, now to my question, how can I iterate the *str pointer and copy the whole content to s and return it?
Thanks in advance
I'd suggest you to not use pointers on string in your case. The following code is probably what you want :
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string lePapel(vector<char> vec){
int j = 0;
vector<char> aux;
aux.resize(6);
for (int i = 57; i <= 62; i++){
aux[j] = vec[j];
j++;
}
string str;
str.reserve(6);
for (int i = 0; i < 6; i++){ str.push_back(aux[i]); }
return str;
}
int main() {
char x[5] = {'A', 'B', 'C', 'B', '4'};
vector<char> vec(x, x + 5);
string s = lePapel(vec);
cout << s;
return 0;
}
Tested here : Tested code
About reserving space to your vector : c++ vector::reserve
Same for strings : reserve for strings
The dynamic array of string objects and the whole aux vector seem completely needless here (unless there's some other purpose for them in your code). Additionally, str is currently causing a memory leak because you never delete it when you're finished.
A much simpler approach is just to append the characters one-at-a-time to the s string object (assuming it's a std::string):
string lePapel(vector<char> vec) {
string s;
for (int i = 57; i <= 62; i++) {
s += vec[i];
}
return s;
}
There are various ways to make the code even shorter (and more efficient) than that though, if you really want to.
EDIT: If you still need/want to iterate your dynamic array and concatenate the contents into s, here's how you could do it:
for (i = 0; i < 6; i++) s += str[i];
delete [] str; //<-- very important!
Short answer, you don't want a string * you want a char *. What you created is a string array. String objects contain a pointer to the char * data you are trying to capture. Also, the sizeof(std::string) (8 bytes in size) is a lot bigger than sizeof(char) (1 byte in size) the second character you store is 8 bytes away from the first character instead of being adjacent.
There are a lot of other C++ style and safety concerns, but I'll stick with the question. ;)
I meet a problem with the char array size. I pass an char array into the function and after run the function, I still want to use sizeof to check the size of the array, it won't give me the new size of the array, but the old size? I would like to know why? Thank you very much!
#include<iostream>
using namespace std;
void replacement(char* arr, int len){
int count=0;
for(int i=0; i<len; i++){
if(arr[i]==' '){
count++;
}
}
int newlen=count*2+len;
//arr[newlen]='\0';
int k=newlen-1;
for(int i=len-1; i>=0; i--){
if(arr[i]!=' '){
arr[k--]=arr[i];
}
else{
arr[k--]='0';
arr[k--]='2';
arr[k--]='%';
}
}
}
int main(){
char arr[]="ab c d e g ";
cout<<sizeof(arr)<<endl;
replacement(arr, sizeof(arr));
int i=0;
while(arr[i]!=NULL) cout<<arr[i];
}
You can't change an array's size. If you want to know the length of the string in the array, use strlen() -- this counts the number of characters before the null terminator.
Even better would be to use C++ std::string class.
Right, so you are trying to replace spaces with "%20", right?
Since C++ (or C) doesn't allow an existing array to be resized, you will either need to have enough space in the first place, or use an array allocated on the heap. Then allocate a new "replacement" string in the replacement function and return that.
The proper C++ method of doing this is of course to use std::string, in which case you could just pass it in as a reference, and do the replacement in the existing variable:
void replacement(std::string* str, int len){
std::string perc20 = "%20";
std::string space = " ";
while((pos = str.find(space, pos)) != std::string::npos)
{
str.replace(pos, space.length(), perc20);
pos += perc20.length();
}
}
Much easier...
You can use sizeof() to find the size of only static arrays when the size is known at compile time. Hence it will always return the size of the array as determined at compile time.
Your program technically has Undefined Behavior because your use of sizeof returns the size in bytes of your char array. But a char implicitly contains a null byte \0. That means the for loop is iterating 1 past the length of the array.
It's recommended that you use std::string along with its size member function instead.
I have just started to learn c++. I also want to clear that this is no homework question, its just something that I am stuck on.
I was going through assignment questions on the MIT website, and i have pasted the question for you here;
Write a function that returns the length of a string (char *), excluding the final NULL character. It should not use any standard-library functions. You may use arithmetic and dereference operators,but nottheindexing operator([]).
I don't know how to do this without an array.
Any help is appreciated!!
This is what i did:
#include<iostream>
#include<conio.h>
#include<string>
using namespace std;
int stringlength (char* numptr);
int main()
{
char *mystring;
cout<<"enter the string \n";
cin>>mystring;
cout<<"length is "<<stringlength(mystring);
getch();
}
int stringlength (char* numptr)
{
int count=0;
for(;*numptr<'\0';*numptr++)
{
count++;
}
return(count);
}
This is what i had done previously before I asked u all about the problem.
But this got me an answer of zero.
But if in my function i change *numptr<'\0' to *numptr!= 0, i get the right answer.
Now what i am confused about is, isn't that the null character, so why cant i check for that.
Since you are doing this as an educational thing, I'm not gonna give you the answer. But I will help you a little on the way.
Use a char* and the ++ operator to check for terminating zero \0 this will be the last character in the string.
First of all, this is not the way to learn C++ in 2013. The answer relies on low-level pointer manipulation. There are a lot more important things to learn about C++ before you get to this point. Right now, you should be learning about string, vector, functions, classes, and not about these low-level details.
To answer you question, you have to know how strings are represented. They are represented as an array of characters. In C and C++, arrays do not have a built in length. So you have to store it or use some other means of finding the length. The way the strings make is so you can find the length is that they store a 0, as the last position in the array. Thus "Hello" would be stored as
{'H','e','l','l','o',0}
To find the length you go through the array starting at index 0 and stop when you encounter a character value of 0;
The code would look something like this
int length(const char* str){
int i = 0;
for(; str[i] != 0; i++);
return i;
}
Now in C and C++ you can str[i] is the same as *(str + i);
So to satisfy your question you can write it like this
int length(const char* str){
int i = 0;
for(; *(str + i) != 0; i++);
return i;
}
Now, instead of using + i, you can increment str directly;
int length(const char* str){
int i = 0;
for(; *str++ != 0; i++){;
return i;
}
Now in C, a value is false if it is 0, otherwise it is true, so we do not need the != 0, so we can write
int length(const char* str){
int i = 0;
for(; *str++; i++){;
return i;
}
#include<iostream>
#include<conio.h>
#include<string>
using namespace std;
int stringlength (char* numptr);
int main()
{
char *mystring;
cout<<"enter the string \n";
cin>>mystring;
cout<<"length is "<<stringlength(mystring);
getch();
}
int stringlength (char* numptr)
{
int count=0;
for(;*numptr<0;*numptr++)
{
count++;
}
return(count);
}