Welcome Guest ( Log In | Click here to Register a free account now! )
Welcome to Bleeping Computer, a free community where people like yourself come together to discuss and learn how to use their computers. Using the site is easy and fun. As a guest, you can browse and view the various discussions in the forums, but can not create a new topic or reply to an existing one unless you are logged in. Other benefits of registering an account are subscribing to topics and forums, creating a blog, and having no ads shown anywhere on the site.| Important Announcement: The winners of the BC Million Post contest have been announced. You can read who the winners are at this post. - BleepingComputer Management |
![]() ![]() |
Jul 3 2008, 12:01 PM
Post
#1
|
|
![]() Member ![]() ![]() Group: Members Posts: 36 Joined: 14-May 08 Member No.: 209,042 |
I am working on a program that is meant to return values to another app based on certain chars entered into the program. It is not important what they do, since that is off topic. What I do need to know is why my conditional operator isn't being evaluated. This condition is only meant to check if a value of argv[1 through argc-1] in a nested loop, and set an array value called "flag" to 1 that is incremented in the base loop. This is the header for my program. quosym.h #include <stdio.h> char file_quosym[10]={'@','$','#','&','x','[','(','s','*'}; Just a simple 2 lines, array intended to be global obviously. And here is the program. CODE #include "quosym.h" int main(int argc,char *argv[]) { int flag[10]={0}, i=0, j, ret; while (argc--) //Until argvs last valid index is reached { for (j=0; j<9; j++) //Run through fil_quosym array for every char in argv { flag[j]+=((char)argv[i]==file_quosym[j]) ? (1) : (0); } i++;//Head to next value in argv } return 0; //Ignore this. Still pondering proper way to return it. } This was my error message from the compiler (Dev C++) ISO C++ forbids comparison between pointer and integer This was indifferent whether the char typecast was there or not. Changing the ?: to an if ((char)argv[i]==file_quosym[j]) was no different. Am I unable to get char values from argv? What's my best course of action here? This post has been edited by zyrolasting: Jul 3 2008, 12:04 PM |
|
|
|
Jul 3 2008, 10:08 PM
Post
#2
|
|
|
Multi Megaton Malware Munition ![]() ![]() ![]() ![]() ![]() ![]() Group: HJT Team Posts: 4,882 Joined: 17-January 08 From: Northfield, Ohio Member No.: 184,215 |
Youre problem is that you are refrencing a pointer. argv contains an array of pointers, which themselves point to arrays of null terminated character arrays. Argv does not contain the actual values.
Each seperate command parameter from the command line is passed as a seperate array. And each pointer is to a null terminated string of the command line option. So if I do program.exe -yes -something -two Then argv will contain four memmory addresses. The first points to a null terminated string "program.exe". The next points to a null terminated string "-yes". And the next "-something", and "-two" after that. Do you know what a pointer is? Billy3 -------------------- The forum is always a busy place. In the event I fail to reply within twenty-four hours, feel free to send me a PM.
|
|
|
|
Jul 3 2008, 10:10 PM
Post
#3
|
|
|
Multi Megaton Malware Munition ![]() ![]() ![]() ![]() ![]() ![]() Group: HJT Team Posts: 4,882 Joined: 17-January 08 From: Northfield, Ohio Member No.: 184,215 |
Also, what is "fil_quosym" and array of? Integers, characters, floats?
Billy3 -------------------- The forum is always a busy place. In the event I fail to reply within twenty-four hours, feel free to send me a PM.
|
|
|
|
Jul 4 2008, 01:08 AM
Post
#4
|
|
![]() Member ![]() ![]() Group: Members Posts: 36 Joined: 14-May 08 Member No.: 209,042 |
I am not able to get to my compiler right now, so I'm just running off what is available here.
I do know about pointers, but I did not yet grasp the concept of an array of pointers. Simply because I am novice and all that did was make me a bit disoriented. Mostly due to how I assign and access deeper values. By the way, you just read a typo in a comment. It's file_quosym, and if you look at my first post again you see it in the header, above the codebox (Just 2 lines). It's char. Alright, so what if I just add another asterisk to argv[i] in my for loop? If I were to make a guess, it would seem it's just stepping down a hierarchy. Please let me know if that's a mistake. Also, I saw some weird banner ad embed in my first post. I have not seen that happen in this kind of forum. What's that about? |
|
|
|
Jul 4 2008, 06:08 AM
Post
#5
|
|
|
Multi Megaton Malware Munition ![]() ![]() ![]() ![]() ![]() ![]() Group: HJT Team Posts: 4,882 Joined: 17-January 08 From: Northfield, Ohio Member No.: 184,215 |
Ads are embeded for some user accounts. If you wern't logged in, you might of seen it.
The asterisk is basicly what it boils down to. The one line inside the while loop can be something like this: CODE char tempchar; tempchar = *(argv[i]); //Since a pointer to an array is a pointer to the first element in the array, we don't have to subscript it. if (tempchar == file_quosym[j]) flag[j]++; I put in the extra char variable so you could see what's going on easier. Of course, you could put *(argv[i]) in for tempchar in the if statement and save a few lines ;) Hope that helps! Billy3 -------------------- The forum is always a busy place. In the event I fail to reply within twenty-four hours, feel free to send me a PM.
|
|
|
|
Jul 4 2008, 11:03 AM
Post
#6
|
|
![]() Member ![]() ![]() Group: Members Posts: 36 Joined: 14-May 08 Member No.: 209,042 |
I'm thrilled to say I got some response from the program, but it's still being a bit argumentative. (heh) Your suggestion has fixed the issue of evaluating and returning an expression, but apparently
my issue now resides in argv. I looked up that the valid argument I tested "@$#" only had @ printed back to me (printf added to source). I recall that these arguments can be split by white spaces, so I need to access one level deeper to grab the characters I need. In other words, I only need the chars in argv[1]. Now that that is cleared, I probably should remove the i increment, but I figured I'd try to find another use for it. I could do "@ $ #" but that would be cumbersome for the app this is intended for. CODE #include "quosym.h" int main(int argc,char *argv[]) { int flag[10]={0}, i=0, j, ret; while (argc--) //Until argvs last valid index is reached { for (j=0; j<9; j++) /*Run through file_quosym array for every char in argv*/ { flag[j]+=(*(*argv[1])+i==file_quosym[j]) ? (1) : (0); /*Changed here, w and w/o parenthesis. Attempts to step down in char array in argv[1] to ind i.*/ if (flag[j]) printf("Quosym %c detected",file_quosym[j]); i++; //Moved to nested, and also tried just below at the original line. } } return 0; } That crashed and burned. To be honest, again I have no clue what I'm doing when it comes to accurately accessing an array of pointers. So can you tell me anything about accessing the char array of argv[1]? This post has been edited by zyrolasting: Jul 4 2008, 11:04 AM |
|
|
|
Jul 4 2008, 04:07 PM
Post
#7
|
|
|
Multi Megaton Malware Munition ![]() ![]() ![]() ![]() ![]() ![]() Group: HJT Team Posts: 4,882 Joined: 17-January 08 From: Northfield, Ohio Member No.: 184,215 |
argv <-- array of pointers
argv[1] <-- Access the second element in the array of pointers, or the second command line string (We want to skip the first argument, which is always the name of the program itself. *(argv[1]) <- Now we have a pointer to a null teriminated character array of the characters *(argv[1] + 1) <-- Add the width of one character to the memory address before getting the value, this will get the next char. (*(argv[1]))[1] <-- Same as above using sub scripting instead of pointer arithmetic *(argv[1] + 2) <---+-- Access the third character in the array (*(argv[1]))[2] <--/ It should be noted that C allows access to random ram when you, for example, read beyond the end of a null terminated character string. Because the string ends with a null (a zero, not the ascii equivelent but \0), if you want to loop the string you can typically do this: char *charPointer; charPointer = argv[1]; while(*charPointer) { //Do something using *(charPointer) as the current character charpointer++; } Does that help? Billy3 -------------------- The forum is always a busy place. In the event I fail to reply within twenty-four hours, feel free to send me a PM.
|
|
|
|
Jul 4 2008, 04:09 PM
Post
#8
|
|
|
Multi Megaton Malware Munition ![]() ![]() ![]() ![]() ![]() ![]() Group: HJT Team Posts: 4,882 Joined: 17-January 08 From: Northfield, Ohio Member No.: 184,215 |
Oh, let me throw in that pointer arithmatic is usually MUCH faster ;)
I suggest you read this: http://www.cplusplus.com/doc/tutorial/pointers.html Billy3 -------------------- The forum is always a busy place. In the event I fail to reply within twenty-four hours, feel free to send me a PM.
|
|
|
|
Jul 5 2008, 01:58 AM
Post
#9
|
|
![]() Member ![]() ![]() Group: Members Posts: 36 Joined: 14-May 08 Member No.: 209,042 |
Alright, we've got progress but we're still not in the clear. Thanks so much for input thus far!
The code is now reading in one entry, but the read and what I am told is found is erratic. Right now my only concern is that the program is understanding the set chars for file_quosym in order. My header remains unchanged #include <stdio.h> char file_quosym[10]={'@','$','#','&','x','[','(','s','*'}; Say if my passed argument was @#$. Indexes 1, 3 and 2 respectively. Printf tells me... detected @ detected @ detected # Indexes 0,0,2 were read out of the run. I assumed that values could interfere with printf's control string (doubt it) so I messed around with values. Please check these returns below. $$# detected $ detected $ Indexes 1,1, no attempt to continue. $@# detected $ detected @ detected $ Indexes 1,0,1. Offset/Innacurate 3rd run, defies cPoint++ in code below. Here is my updated source, following your recent advice. I hit another block, since I believe there is something wrong with the position of the char array of argv[1]. Of course, with starting at it's first char and incrementing by 1 I have no idea where it flops. Please inform me of my error. I read the link you sent. I did still grasp the first few sections, but the pointer arithmetic and everything following was useful to know. Thanks! Oh, and just in case the above mentioned index 0 is blurring things, it's just making sure that only file_quosym and flag remain parallel. I'm sure you caught that, but I'm just mentioning as a precaution. CODE #include "quosym.h"
int main(int argc,char *argv[]) { int flag[10]={0}, j; char *cPoint; cPoint=argv[1]; while (argc--) //Until argvs last valid index is reached { for (j=0; j<9; j++) /*Run through file_quosym array for every char in argv*/ { flag[j]+=((*(cPoint))==file_quosym[j])?(1):(0); if (flag[j]) printf("%c detected.\n",file_quosym[j]); } cPoint++; } return 0; } This post has been edited by zyrolasting: Jul 5 2008, 02:08 AM |
|
|
|
Jul 5 2008, 09:01 AM
Post
#10
|
|
|
Multi Megaton Malware Munition ![]() ![]() ![]() ![]() ![]() ![]() Group: HJT Team Posts: 4,882 Joined: 17-January 08 From: Northfield, Ohio Member No.: 184,215 |
Change this line:
flag[j]+=((*(cPoint))==file_quosym[j])?(1):(0); to this: flag[j] = ((*(cPoint))==file_quosym[j])?(1):(0);. You can't add to values in flag because you don't know what they are. You only initialized the first index of flag, not the other ones. So, flag[0] = 0, flag[1] = ????? See if that works. Also, please let me know exactly what you're trying to do. I will write a function that does what you're trying to do and walk through it with you, if you wish ;) Billy3 -------------------- The forum is always a busy place. In the event I fail to reply within twenty-four hours, feel free to send me a PM.
|
|
|
|
Jul 5 2008, 01:00 PM
Post
#11
|
|
![]() Member ![]() ![]() Group: Members Posts: 36 Joined: 14-May 08 Member No.: 209,042 |
The program began reading correctly, but is now always stopping after two checks of char.
Such as @#$ prints @# or $#@ to $# Alright, I'll explain my function as best I can. I have a homebrew video game that is managed by an engine I designed in another language. It communicates with the file system by loading copies for the game, and manipulating them as it is loaded with characters assigned to the file. These are what I called the quosyms, which is just a fictitious name I based on something. Each character is checked, and a flag is toggled to 1 every time one of these chars is found. This prepares the game for the altered loaded file, since the host game is the app that does the manipulating. This app is meant to return the flags set, which I am pondering how since arrays can't be exported easily. I do have a script that can pull values by separation in string. For example, if I made a return "1|0|1|0|0|1|" (a string) the script outside I wrote would read this and get 101001, even though that was all of the flag elements. So since I understand a complete array return is impossible I would like to return a string version of them all added together. I was thinking another for loop and typecast values, but I did not know how exactly to combine them. So to summarize -Flag array zeroed out before read begins. -Reads chars that flag a file. -Compares the next char to the index. If there is a match, a flag with the same element as the char is toggled to 1. Everything else is ignored. -This is done by a for loop doing a sequential step through both flag and file_quosym. -Returns a string version of all flag elements. I really would appreciate a walk through for the sake of learning a better way, but you really don't have to do that. Just some advice and suggestions on my return issue along with the one index early stop would be great. Thanks so much for your help thus far! |
|
|
|
Jul 5 2008, 01:34 PM
Post
#12
|
|
|
Multi Megaton Malware Munition ![]() ![]() ![]() ![]() ![]() ![]() Group: HJT Team Posts: 4,882 Joined: 17-January 08 From: Northfield, Ohio Member No.: 184,215 |
Does the order of the members matter? In other words, if I pass #$?, should that return the same result as ?#$ in your result string-ized array?
Billy3 -------------------- The forum is always a busy place. In the event I fail to reply within twenty-four hours, feel free to send me a PM.
|
|
|
|
Jul 5 2008, 05:46 PM
Post
#13
|
|
|
Multi Megaton Malware Munition ![]() ![]() ![]() ![]() ![]() ![]() Group: HJT Team Posts: 4,882 Joined: 17-January 08 From: Northfield, Ohio Member No.: 184,215 |
Have fun with this:
CODE #include <iostream> //required for cout #include <cstdlib> //required for strlen and the EXIT_SUCESS macro using namespace std; char file_quosym[]="@$#&x[(s*"; //file_quosim is a null terminated character array who's size is determined at compile time by the compiler int main(int argc,char *argv[]) { char *flags, *workingFileQuosym; workingFileQuosym = file_quosym; flags = new char[strlen(file_quosym) + 1]; //create another null terminated string flags[strlen(file_quosym)] = '\0'; //we want a result of a null terminated string, so null the thing out. while(*(workingFileQuosym)) { //loop through each character we're searching for flags[workingFileQuosym-file_quosym] = '0'; //zero out the character we're in. for (int idx = 1; idx < argc; idx++) { //loop through each argument, starting with the second index (Skip program name) bool stop = false; //this is just a holder variable so that we can break out of both loops at once char *currentArg = argv[idx]; //get the current null terminate while (*(currentArg)) { //loop through the null terminated string if (*currentArg == *workingFileQuosym) { cout << "Found character: " << *workingFileQuosym << endl; //Do you really need a comment for this? flags[workingFileQuosym-file_quosym] = '1'; //we've found a character, so set this character to 1 stop = true; //tell the if below to break us out of this while break; //break out of the while loop we're in } currentArg++; } if (stop) { break; } //if we need to get out of the for loop because we've found the character, we need to stop looping and start looking for the next character. This breaks out of the for loop. } workingFileQuosym++; } cout << flags; delete [] flags; return EXIT_SUCCESS; } Billy3 -------------------- The forum is always a busy place. In the event I fail to reply within twenty-four hours, feel free to send me a PM.
|
|
|
|
Jul 6 2008, 04:57 AM
Post
#14
|
|
![]() Member ![]() ![]() Group: Members Posts: 36 Joined: 14-May 08 Member No.: 209,042 |
Thank you so very much for the app! Works beautifully. (It did spit back out * and & strangely, obviously can't be helped there. =P) However, I would still like to learn my mistakes or limits with my last attempt.
But I must ask, is this many lines necessary? I'd like to learn what you've got here, so I can keep trying this kind of thing on my own. |
|
|
|
Jul 6 2008, 07:28 AM
Post
#15
|
|
|
Multi Megaton Malware Munition ![]() ![]() ![]() ![]() ![]() ![]() Group: HJT Team Posts: 4,882 Joined: 17-January 08 From: Northfield, Ohio Member No.: 184,215 |
It can be done in fewer lines, however, lots of those lines allow easier configuration. For example, since none of the array sizes are hard coded, you can do this:
Change this line: char file_quosym[]="@$#&x[(s*"; to this: char file_quosym[]="@$#somemorechars&x[(s*"; and recompile. The program still operates correctly, and will not require modification. Also, even though there are a lot of lines, it will probably run faster than the sub scripted function, because sub scripting requires the compiler to add x amount of memory addresses to the pointer that holds the array each time you reference it. By simply moving the pointer manually up the array, using the VERY fast and efficient increment operator (++), you cant really make anything run much faster. This program relies on two fundamental concepts to c(++). Pointers, which I already showed you earlier, and Null Terminated Strings. See here for info on those: http://www.cplusplus.com/doc/tutorial/ntcs.html C relies much more on pointers than at first glance. All arrays are pointers. All arrays can be accessed by pointers, and are usually looped with pointers. I would also like to highly recomend Visual Studio as your ide, which is free here: http://www.microsoft.com/express/vc/ The debugger is much better put together Billy3 -------------------- The forum is always a busy place. In the event I fail to reply within twenty-four hours, feel free to send me a PM.
|
|
|
|
![]() ![]() |
| Lo-Fi Version | Time is now: 23rd November 2008 - 08:13 AM |