Having trouble getting GET variables from url - c++

I'm having trouble with this algorithm to extract the get variables from a url and print them each on a new line like:
x=y
z=hello
etc. but instead it prints a seemingly random section of the url with no newlines to the file. There must be a logic error of some kind but i just can't spot it.
for(i_m=0;i_m<len_m;i_m++) {
if(var_m[i_m]=='&') {
fwrite(var_m+offset_m, 1, amp_m, echo_out);
fputc('\n',echo_out);
offset_m+=amp_m;
amp_m=0;
}
amp_m++;
}
any help appreciated.
EDIT:
thank you everyone for your comments, I corrected that error Guss but to no avail. I thought up another algorithm, since I can't use c++ strings in this one
while((i_m=(strchr(var_m,'&')-var_m))>0) {
var_m[i_m]='\n';
}
Which would change each of the & to a newline, and then I could just write var_m to the file, but for some reason this gives me a buffer overflow.

void StringExplode(std::string &str, const std::string &separator, std::vector<string>* results){
int found;
found = str.find_first_of(separator);
while(found != string::npos){
if(found > 0){
results->push_back(str.substr(0,found));
}
str = str.substr(found+1);
found = str.find_first_of(separator);
}
if(str.length() > 0){
results->push_back(str);
}
}

your accounting of offset_m and amp_m seems to be wrong. Take for example the simple string "a&b&c" - your code should have outputed from that the text:
a
b
c
but if you trace through the code you will see that when you get to the first & then offset_m=0 and amp_m=1 and you'd print a - which is Ok but when you get to the second & then offset_m=1 and amp_m=2 which would actually print &b and at no point you'd print the last element.
Using a simple string splitting algorithm like mysqlforums suggested is a common way to handle this task, but I believe you should be able to come up with a simple loop algorithm that will get you what you need. think about it again and try to run through the algorithm in your head (or using pen and paper) to try to understand how it works - I'm sure you'll get it!
If you're still having problems, post something here and I'll try to help again.

Related

Binary search of a word

Im very new to programming and I'm currently trying to write a code for binary search of a word in .txt file using vector. The program checks if the word is found if not the searched word is written to the .txt file .The problem is I'm not quite sure I use std::vector correctly and I'm almost sure there is a big problem with my BinarySearch() function.I have read almost every code on the internet for binary_search but I just can't make it work. I can really use some help... The txt file is sorted(one word on each row).The current code finds only 2-3 out of 15 words.Here is my latest attempt:
void BinarySearch(vector<string> cont,string s)
{
int middle;
int first=0;
int leng=cont.size();
int last=leng-1;
bool found=false;
while(first<=last && !found)
{
middle=(first+last)/2;
if(cont[middle]==s)
{
found=true;
}
else {
if(cont[middle]<s)
{
last=middle-1;
}
else
{
first=middle+1;
You were extremely close. But you've got to learn to use the debugger, cause this is a pretty simple catch. This line: if(container[middle]<search) is saying:
Get container's element at middle
Compare it to search
If it comes alphabetically earlier execute the if-block, otherwise execute the else-block
The if-block moves last to search the alphabetically earlier strings, which is the opposite of what you want. This line should have said:
if(container[middle] > search)
Here's a Live example of your code working perfectly after I changed that character: http://ideone.com/vvbONO
Sounds like this is a programming assignment, in which case your teacher probably wouldn't be happy with you solving it like this, but since you have correctly used a sorted vector<string> you can also use: binary_search to completely replace your BinarySearch. Just replace this:
BinarySearch(sWord,find);
With:
cout << (binary_search(cbegin(sWord), cend(sWord), find) ? "word is found" : "Not found") << endl;
If you have questions, comment away!

string::std find method always find a character, even when it's not in the string

I'm doing a project for school where we are parsing through strings passed in from a text file. However, I'm having problems with string.find. When I run this code:
string theFile;
while (inFile)
{
inFile.getline(line, 512);
theFile = line;
bool parsing = true;
while (parsing){
Choice *newChoice = new Choice;
if (theFile.find("|")!= -1) {
newChoice->lines = theFile.substr(theFile.find("%") + 1, theFile.find("|") - 1);
theFile.erase(0, theFile.find("|") + 2);
tempNPC->choices.push_back(newChoice);
}
else
parsing = false;
The input looks something like this:
| d1% stuff | d2% more stuff |
My problem: the if statement is never false. Even once theFile is empty, it still runs the code and thus I get an out-of-bounds error. Any idea why find("|") isn't working?
*Edited to add how I get the string from the file
You might want to look at some documentation, so you can find out what the return values from std::string::find actually mean. Specifically, if you're not sure a value is present you should compare it to npos before using it, not "-1". And the problem with it continuing to run after your input's exhausted is likely best solved in the input code you don't show, rather than trying to parse some string that may or may not be actual input.
UPDATE: as speculated in my comment to vsoftco below, your input logic is broken. Use this:
while (getline(inFile, theFile))
...

No methods of read a file seem to work, all return nothing - C++

EDIT: Problem solved! Turns out Windows 7 wont let me read/ write to files without explicitly running as administrator. So if i run as admin it works fine, if i dont i get the weird results i explain below.
I've been trying to get a part of a larger program of mine to read a file.
Despite trying multiple methods(istream::getline, std::getline, using the >> operator etc) All of them return with either /0, blank or a random number/what ever i initialised the var with.
My first thought was that the file didn't exist or couldn't be opened, however the state flags .good, .bad and .eof all indicate no problems and the file im trying to read is certainly in the same directory as the debug .exe and contains data.
I'd most like to use istream::getline to read lines into a char array, however reading lines into a string array is possible too.
My current code looks like this:
void startup::load_settings(char filename[]) //master function for opening a file.
{
int i = 0; //count variable
int num = 0; //var containing all the lines we read.
char line[5];
ifstream settings_file (settings.inf);
if (settings_file.is_open());
{
while (settings_file.good())
{
settings_file.getline(line, 5);
cout << line;
}
}
return;
}
As said above, it compiles but just puts /0 into every element of the char array much like all the other methods i've tried.
Thanks for any help.
Firstly your code is not complete, what is settings.inf ?
Secondly most probably your reading everything fine, but the way you are printing is cumbersome
cout << line; where char line[5]; be sure that the last element of the array is \0.
You can do something like this.
line[4] = '\0' or you can manually print the values of each element in array in a loop.
Also you can try printing the character codes in hex for example. Because the values (character codes) in array might be not from the visible character range of ASCII symbols. You can do it like this for example :
cout << hex << (int)line[i]

Unknown reason behind out_of_range error for substring

UPDATE: Yes, answered and solved. I also then managed to find the issue with the output that was the real problem I was having. I had thought the substring error was behind it, but I was wrong, as when that had been fixed, the output issue persisted. I found that it was a simple mix up in the calculations. I had been subtracting 726 instead of 762. I could've had this done hours ago... Lulz. That's all I can say... Lulz.
I am teaching myself C++ (with the tutorial from their website). I have jumped ahead time to time when I have needed to do something I cannot with what I have learned so far. Additionally, I wrote this relatively quickly. So, if my code looks inelegant or otherwise unacceptable at a professional level, please do excuse that for now. My only current purpose is to get this question answered.
This program takes each line of a text file I have. Note that the text file's lines look like this:
.123.456.789
It has 366 lines. The program I first wrote to deal with this had me input each of the three numbers for each line manually. As I'm sure you can imagine, that was extremely inefficient. This program's purpose is to take each number out of the text file and perform functions and output the results to another text file. It does this per line until it reaches the end of the file.
I have read up more on what could cause this error, but I cannot find the cause of it in my case. Here is the bit of the code that I believe to contain the cause of the problem:
int main()
{
double a;
double b;
double c;
double d;
double e;
string search; //The string for lines fetched from the text file
string conversion;
string searcha; //Characters 1-3 of search are inserted to this string.
string searchb; //Characters 5-7 of search are inserted to this string.
string searchc; //Characters 9-11 of search are inserted to this string.
string subsearch; //Used with the substring to fetch individual characters.
string empty;
fstream convfil;
convfil.open("/home/user/Documents/MPrograms/filename.txt", ios::in);
if (convfil.is_open())
{
while (convfil.good())
{
getline(convfil,search); //Fetch line from text file
searcha = empty;
searchb = empty;
searchc = empty;
/*From here to the end seems to be the problem.
I provided code from the beginning of the program
to make sure that if I were erring earlier in the code,
someone would be able to catch that.*/
for (int i=1; i<4; ++i)
{
subsearch = search.substr(i,1);
searcha.insert(searcha.length(),subsearch);
a = atof(searcha.c_str());
}
for (int i=5; i<8; ++i)
{
subsearch = search.substr(i,1);
searchb.insert(searchb.length(),subsearch);
b = atof(searchb.c_str());
}
for (int i=9; i<search.length(); ++i)
{
subsearch = search.substr(i,1);
searchc.insert(searchc.length(),subsearch);
c = atof(searchc.c_str());
}
I usually teach myself how to get around these issues when they come up by looking at references and problems other people may have had, but I couldn't find anything that helped me in this instance. I have tried numerous variations upon this, but as the issue has something to do with the substring and I couldn't get rid of the substring in any of these variations, all returned the same error and the same result in the output file.
This is a problem:
while (convfil.good()) {
getline(convfil,search); //Fetch line from text file
You test for failure before you do the operation that can fail. When getline does fail, you're already inside the loop.
As a result, your code tries to process an invalid record at the end.
Instead try
while (getline(convfil,search)) { //Fetch line from text file
or even
while (getline(convfil,search) && search.length() > 9) {
which will also stop without error if there's a blank line at the end of the file.
It's possible you are reading a blank line at the end of the file and trying to process it.
Test for an empty string before processing it.

String being duplicated in vector array

Edit: Changed the title to better reflect the current issue.
Right i know now were the source of the issue lies, it's with the text splitting part of the function. I remember now what i did, i changed the splitting text because the tutorial for me was returning an error.
for(const char *c=text;*c;c++)
{
if(*c=='\n') {
string line;
for(const char *n=start_line;n<c;n++) line.append(1,*n);
lines.push_back(line);
start_line=c+1;
}
}
if(start_line)
{
string line;
for(const char *n=start_line; n < c;n++) line.append(1,*n);
lines.push_back(line);
}
The 'c' was returning undeclared, and there's no mention for any other c, so i guess it's referring to the pointer in the for loop above. Though bring the "if (start_line)" into the first code block, kept returning me each character in the text, instead of just the whole thing.
So i changed the code to the following:
for(const char *c=text;*c;c++)
{
if(*c=='\n')
{
string line;
for(const char *n=start_line;n<c;n++) line.append(1,*n);
lines.push_back(line);
start_line=c+1;
if(start_line)
{
string line;
for(const char *n=start_line;n<c;n++) line.append(1,*n);
lines.push_back(line);
}
}
else if (*c == *start_line)
{
lines.push_back(text);
}
}
I pretty sure that the "else if (*c == *start_line)" comparsion is what's causing me the issue. Unsure though what to replace it with. I guess though because i'm not using any newlines or don't plan to i can just go with:
for(const char *c=text;*c;c++)
{
lines.push_back(text);
break;
}
But it would still be nice to know were i was going wrong. *Note: That the above code works fine now, no issue with that and the doubling effect. So i'm sure that it was my text splitting code.
Here's an idea for you: in your text rendering method, add a static counter and use it to set the color of each string rendered. Since you don't seem to have that many strings per frame, you can use the 8 bits of one color component (e.g. red) for the counter and set the 2 other components to 255. If you had more than 255 strings, you could still encode the counter value over 2 or 3 color components.
With this little debug aid, you will be able to see in which order each piece of text is rendered. You can use pixie and/or zoomin to see the pixel values "live". Otherwise, just take a screenshot and examine the result.
It looks like the erroneously drawn text in that capture is "50b" which I doubt is a string that would normally appear in your game. It looks like you're drawing something that's normally an empty string, but sometimes picks up junk values - in other words, undefined behavior.
I can't be sure, of course, because I simply don't have enough information to find your problem. Your glClear looks fine to me, so you can be assured that the extra text is being drawn in the same frame as your intended text.