How to know the position of the character? [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
How to find the first occurrence of a character from the end, but at the same time indicate the position of the end of the string at which to look for?
Ie we need the following function.
lastIndexOf(char c, int position_from_end);
As will be:
QString s("abcadc");
int i = s.mylastIndexOf('c', 0) //6
.
QString s1("abcadc");
int j = s1.mylastIndexOf('c', 1) //3

In c++, use the std::string method rfind(char c, size_t pos)
The character will be searched for in the part of the string which comes before index pos. (If you were to use the version of rfind which searches for a substring, the first character of the match must come before pos).
pos defaults to string::npos, which is larger than any valid string index and therefore causes the search to start at the end of the string.
It returns string::npos if no match is found.
If you want to specify the offset from the end of the string, you can subtract the offset from the string's length:
std::string s;
//...
size_t p = s.rfind(ch, s.size() - offset);

Related

Given a string output it in a specific way using recursion? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 months ago.
Improve this question
Given a string we have to output the string in a special way.
• If the string consists of one char, we output that char normally.
• Otherwise, we divide the string into two equal parts (if the number of letters in the substr is odd, the second part of the substr will be one letter longer than the first), and we output the first part twice and then the second part (according to the same rules).
For example, let's assume that we want to output the string YOGURT. We divide that string into two equal parts: YOG and URT.
How will we output the substr YOG? Again, it will be divided into two parts - Y and OG. The substr Y we output normally (but in the output of the substr YOG we will do it twice), and the substr OG we output as OOG. So the substr YOG we output as YYOOG.
Analogously, the substr URT is going to give the output UURRT. So the string YOGURT is going to be output as YYOOGYYOOGUURRT.
Length of the string can at max be 10000.
Now I tried using a non recursion way to solve this problem but it was way to slow so I have come to an conclusion I have to do this with recursion. And since I don't have that much experience with recursion I would really need some help.
This is very naturally implemented with recursion like so:
void print(std::string_view s) {
if (s.size() <= 1) std::cout << s;
else {
auto m = s.size() / 2;
print(s.substr(0, m));
print(s.substr(0, m));
print(s.substr(m));
}
}

Having some confusion with pointers [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 11 months ago.
Improve this question
I have the following code that I'm trying to decipher from a former colleague:
void getIP(int p){
char tstr[80];
char *pt;
strcpy(ipBuf,"NA");
if(p==-1)return;
strcpy(tstr, panes[p].stream.c_str());
pt=strchr(tstr,':');
if(pt){
*pt='x'; //Blank first one
pt=strchr(tstr,':');
if(pt){
*pt='\0';
strcpy(ipBuf,&tstr[7]);
}
}
}
I'm relatively inexperienced with C++ so was hoping I could get some help with how this code works. Its purpose I think is to take a camera stream address and strip the port number and any extra stuff off to just give an IP address. I cannot understand through how it achieves this other than it seems to use ":" as a delimiter at a couple of stages?
To explain the function a little more, int p is a position on the grid, then it takes the stream address from that grid square and puts it into tstr.
But any explanation beyond that is much appreciated.
I [...] was hoping I could get some help with how this code works.
strcpy(tstr, panes[p].stream.c_str());
Copy the contents of the std::string designated by panes[p].stream into array tstr, yielding an independent copy as a C string.
pt=strchr(tstr,':');
if(pt){
*pt='x'; //Blank first one
Locate the first appearance of a ':' character in the local copy of the string. If the character is found, then replace it with an 'x'.
pt=strchr(tstr,':');
if(pt){
*pt='\0';
Locate the (new) first appearance of a ':' character in the local copy of the string. If it exists, replace it with a '\0', which will be recognized as a string terminator. That is, truncate the string at that point.
strcpy(ipBuf,&tstr[7]);
Copy the contents of the local C string, starting at the eighth character (because arrays are indexed from 0, not from 1), into the space to which ipBuf points. The magic number 7 is suspicious here, but I don't have enough information to be able to determine whether it is erroneous. My guess would be that the code is assuming that the original first colon will always appear at index 6, with the result that the substring between the (original) first and second colons is copied, but there are cleaner, clearer, more efficient ways to do that.
Improved version, with more C++
... and better names, and no unnecessary copying, and explanatory comments:
void getIP(int pane_index){
if (pane_index >= 0) {
// for clarity and convenience
std::string &url_string = panes[pane_index].stream;
// hardcoded per the original code
const size_t ip_offset = 7;
// Locate the first colon, if any, after the start of the ip address
size_t colon_index = url_string.find(':', ip_offset);
if (colon_index != std::string::npos) {
// Extract the name / IP address as the substring starting at
// offset 7 and stopping just before the second colon
size_t ip_len = colon_index - ip_offset;
strncpy(ipBuf, url_string.c_str() + ip_offset, ip_len);
ipBuf[ip_len] = '\0';
return;
} // else there are no colons after the start of the ip address
} // else an invalid pane index was given
// no machine name / IP address is available
strcpy(ipBuf, "NA");
}
As already noted in the previous comment, the function searches for the second occurence of ':' in tstr string and if it is found, replaces it with null character, effectively cutting off any remaining characters from the string. Than the characters in the string from index [7] to the null character (previously ':') are copied to ipBuf. For example, let say url is rtsp://192.168.0.200:551/stream.sdp. Digit 1 in "192" has index [7] in the string. So copying from that position to the second ":" (or null char) would copy "192.168.0.200".

What does the ":" and "ch" mean in this hash table for loop "for ( char ch : key )"? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I know this may not just be for hash tables but an answer with respect to it will help me better understand it:
int hash (const string & key, int tableSize) {
int hashVal = 0;
for (char ch : key) // ????lost here??? is ch is just any character in the key???
hashVal += ch;
return hashVal % tableSize;
}
A string is considered to be a collection of characters.
Explanation: For each character in the string key, perform the body of the loop.
ch : key
ch is the name of a loop variable, it will be assigned one character at a time from the string called key, and the loop body will be executed with that value of ch iteratively
: this delimits the loop variable from the string.
See "Range-based for loop" (since C++11)

while reading from the text file is finding extra character (ex.'#') even if it is not there? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Here is my code: In this case I am getting '#' which is conflicting with the the '#' in the file
ifstream file("text.dat");
if(file.is_open()){
bool flag=false;
here I am getting a extra character
getline(file,str,'\n');}
Here is the text file, I am reading from this text file!
jim Workshop 5 is cool
harry #jim working on workshop 5 now
chris
dave what the ^#$%!
john #harry I'm done
std::string::find() returns std::string::npos if the character is not found, and std::string::npos is a constant representing max size of a string. It is the huge number that you see.
Your if statements should look like this:
if(std.find('#') != std::string::npos)
{
//blabla
}
Look at the output of your program:
'#' is here!!!!: 18446744073709551615
18446744073709551615 is the value that str.find("#") is returning. find() returns the index of the substring if found, otherwise it returns std::string::npos, which is defined as -1 casted to std::string::size_type, which is an unsigned type. In this case, size_type is a 64bit number, and so you end up with index 18446744073709551615 when npos is returned.
Any non-zero value will evaluate as true in a boolean expression, such as an if statement. That is why you end up setting flag=true. This is a bug in your code for two reasons:
you are evaluating to true when find() does not find a match at all.
you are evaluating to false when find() finds a match at position 0 (the 1st character of the string).
You need to change this:
if(str.find("#")) flag=true;
To this instead:
if(str.find("#") != string::npos) flag=true;
Or simply this:
flag = (str.find("#") != string::npos);
std::string::find() returns std::string::npos if it fails to find the needle, the value of npos is -1, which is coerced to the boolean true, not false.
You need to compare the result of find() to npos directly, instead of doing the implicit coercion.

The string erase() function is giving different results for similar calls [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I tried using the string::erase() function with 2 parameters for the start and the end point but it is giving me different results for the same type of call.
Here is the code:
#include<iostream>
using namespace std;
int main(){
string s = "azxxzy";
s.erase(2,2);
cout << s;
s.erase(1,1);
cout << endl << s;
}
It deletes 2 characters i.e xx for the first call but for the second call it is deleting only one z.
Can you please explain why this is happening?
CORRECTED-
the question is wrong as I used the overloaded version i.e
'string& erase (size_t pos = 0, size_t len = npos); '
But expected the output from
'iterator erase(iterator first,iterator last)'
You're using std::string::erase() with the following synoptic:
string& erase (size_t pos = 0, size_t len = npos);
It will erase the part of the string specified at the position pos with the length len. Note that the position index pos begins with 0. The default parameter for len = npos indicates all characters until the end.
In your example it means:
string s = "azxxzy";
s.erase(2,2); /* azzy: deleting 2 characters from position 2 */
s.erase(1,1); /* azy: deleting 1 character from position 1 */
In my textbook it was written that the 2 parameters of std::string::erase are iterator first and iterator last. That is why I assumed it was giving a strange result.
You mean the overloaded version:
iterator erase (iterator first, iterator last);
But you didn't provide an iterator. You're passing int literals that will be implicitly converted to size_t. In the link I've posted above you can see the overloaded version + example.
I expected the output to be 'ay'
To get that output with iterators do the following with std::string::begin() and std::string::end():
string s = "azxxzy";
s.erase(s.begin() + 1, s.end() - 1); /* ay: deleting characters */
/* between 1st and last character */