[SOLVED] Tried to write something "serious" and have failed once again
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
That's not how I'd remove a word from a string. How incredibly complicated! I'd use strstr() to see the position where the word starts, then I'd transcribe the string up to that point into an empty buffer, jump the length of the word and then transcribe the rest.
In a nutshell strtok splits the string from the configuration line using a comma as the separator. strstr compares the type and if it matches strips the command line arguments. Code is a bit rough and I borrowed a bit from the others but hopefully it is easy to follow.
I tried it again without any changes, and yes strstr() does in fact appear to find the "identifier"/the first string specified to my program on the command-line - I must have missed it before, sorry about that.
Great! Glad you see that.
Quote:
Originally Posted by jsbjsb001
I done a search before starting this thread about how to remove a word from an array, it appears it involves a 2D array, along with some for loops, as well as strcmp() and strcpy() - although I don't really understand exactly what the example code is actually doing to convert the example array to a 2D array, and particularly when it comes to what strcmp() and strcpy() are really doing. This is the example I'm referring to - although I had to use Google Chrome to view that site, as I didn't want to disable Firefox's adblocker.
Not visiting that link, I don't prefer to get sidetracked with some number of references, which is a possibility there.
BAD IDEA to browse the web, see some implementation where you say, "I don't really understand exactly what the example code is actually doing ...", and subsequently subscribe to that example. JUST DON'T! OK?
If you post and if I can discern your problem and give you a solution, I'll probably continue to do so.
Many will agree that with any computer language, there are numerous ways to skin the cat. Learn the easy to understand things. If you absolutely cannot understand a concept, then stay away from it until you get better.
This program you have, you're trying to do a few things: Parse two files, manipulate strings, and then run ffmpeg using an argument list. Along with all of that you're using the argv[] array.
I ALWAYS put in a check for a proper argument list, for when I have one, and I ALWAYS put in a line to illustrate my "usage" when I provide my error report at that check point. What do I mean by that? I have a printf() statement at the top error check saying, "Usage: program-name [argument-1] [argument-2] <optional-argument> ..."
Once again, you're doing too much where you haven't as yet "debugged" the earlier steps of your program.
You get a difficult to resolve situation because while you attain compiled code, you make some fundamental mistakes which cause your program to not do as intended.
What I'm trying to get you to understand is that you're not going back to debug logically, and from the beginning of the program. It would save you a lot of time and grief.
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
Quote:
Originally Posted by hazel
That's not how I'd remove a word from a string. How incredibly complicated! I'd use strstr() to see the position where the word starts, then I'd transcribe the string up to that point into an empty buffer, jump the length of the word and then transcribe the rest.
Yeah, it did seem pretty complicated just to remove one part of the string - glad there's easier ways! Thanks!
Quote:
Originally Posted by rtmistler
Great! Glad you see that.Not visiting that link, I don't prefer to get sidetracked with some number of references, which is a possibility there.
BAD IDEA to browse the web, see some implementation where you say, "I don't really understand exactly what the example code is actually doing ...", and subsequently subscribe to that example. JUST DON'T! OK?
If you post and if I can discern your problem and give you a solution, I'll probably continue to do so.
Many will agree that with any computer language, there are numerous ways to skin the cat. Learn the easy to understand things. If you absolutely cannot understand a concept, then stay away from it until you get better...
Don't worry, I haven't used any of that code, and now I know there's easier ways, I'll take the easier way out for now.
Quote:
I ALWAYS put in a check for a proper argument list, for when I have one, and I ALWAYS put in a line to illustrate my "usage" when I provide my error report at that check point. What do I mean by that? I have a printf() statement at the top error check saying, "Usage: program-name [argument-1] [argument-2] <optional-argument> ..."
I'm not clear on what you mean by "check for a proper argument list"? Do you mean check for what's been typed in by the user? If so, how would I go about doing that?
I was planning on adding a "Usage" function or similar to it. I was just caught up with trying to get it to at least find the "identifier" if nothing else.
Quote:
What I'm trying to get you to understand is that you're not going back to debug logically, and from the beginning of the program. It would save you a lot of time and grief.
I have added some printf's to verify the value of argv[1] for one.
I like michaelk's idea for separating the "identifier" with a comma - it does make it more clear. That way you know whatever is after the comma is what is actually passed to ffmpeg. Thanks for that michaelk!
I'm not clear on what you mean by "check for a proper argument list"? Do you mean check for what's been typed in by the user? If so, how would I go about doing that?
I was planning on adding a "Usage" function or similar to it. I was just caught up with trying to get it to at least find the "identifier" if nothing else.
That's easy. argc contains the total number of command line tokens. The first of these is the program name, so argc-1 is the number of user-supplied arguments. If it is not the number your program requires, print the usage statement and exit.
I'm not clear on what you mean by "check for a proper argument list"? Do you mean check for what's been typed in by the user? If so, how would I go about doing that?
Please follow what hazel said here:
Quote:
Originally Posted by hazel
That's easy. argc contains the total number of command line tokens. The first of these is the program name, so argc-1 is the number of user-supplied arguments. If it is not the number your program requires, print the usage statement and exit.
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
Thanks Hazel and RT. So just to make sure I'm clear; you mean within the following if statement (between fprintf and return 1) to add a line to print out a usage statement?
Code:
if ( argc != 3 ) {
fprintf (stderr, "Missing option or filename\n");
return 1;
}
I've just read the link about functions that ntubski posted before; while other than the part at the bottom about "variable-length argument lists", it seems to make sense; other than the "..." to indicate a "variable-length argument list"; I'm not really clear on much else about "variable-length argument lists".
Also, I was reading michaelk's example code, and while some of it makes sense; I'm not sure why the following is there?
Code:
cmdline[0]="fselect.sh";
(the "fselect.sh" part of it)
But I'll still have to try a few things by themselves to really understand exactly what each line of michaelk's code is actually doing - particularly exactly what strtok(), strcpy() and strcat() are actually doing. While michaelk has explained what the code "as a whole" does, trying to read it and decipher it by itself isn't particularly easy for me, particularly what the functions I mentioned before are really doing (other than what michaelk has already said of course). So I haven't added any more code to my program yet.
Thanks Hazel and RT. So just to make sure I'm clear; you mean within the following if statement (between fprintf and return 1) to add a line to print out a usage statement?
Code:
if ( argc != 3 ) {
fprintf (stderr, "Missing option or filename\n");
return 1;
}
That would certainly work, but the Linux convention is to print a usage statement. In other words, you don't just tell the poor sap he got it wrong; you tell him what he should have input. So put in another fprintf() with something like "Usage: %s THIS THAT THE OTHER", argv[0].
Quote:
I've just read the link about functions that ntubski posted before; while other than the part at the bottom about "variable-length argument lists", it seems to make sense; other than the "..." to indicate a "variable-length argument list"; I'm not really clear on much else about "variable-length argument lists".
Most functions take a fixed number of arguments, but a few do not. The best known of these is probably printf() and its analogues. In such cases, gcc needs to know how many arguments to expect so that it can report any syntax errors. Different functions have different ways of coding this, but there are two main ones:
1) The printf family require you to put placeholders in the string for any variables that it might contain. So in my example above, %s is a placeholder for a string variable inside the quoted string, and argv[0] (the program name) is the variable that goes in there. gcc knows that it should expect one and only one additional variable because there is one placeholder in the string.
2) Some functions require a variable-length list of arguments to end with a NULL pointer. The exec functions that are used to launch programs do it like this. You have a list or an array of command line arguments ending in a NULL.
Quote:
...what strtok(), strcpy() and strcat() are actually doing.
For goodness sake read the man pages for these functions. That's what they are there for. You should never use any function without reading its man page first.
For goodness sake read the man pages for these functions. That's what they are there for. You should never use any function without reading its man page first.
THIS!
And why must you use fprint() to stderr? I know it's valid, but boy I'd hate to have to deal with some odd occurrence where it is actually redirected somewhere else besides the console. Just use plain old printf(). Similarly you were using fputs() at one point too. When you're learning, why complicate things?
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
Thanks for explaining that Hazel - it's at least little more clear. Although I'm still not sure about what to make of the examples for "variable-length argument lists" in that same link that ntubski posted before though.
I was planning to read the man pages about those functions - that's why I said I haven't added any more code to my program. So it doesn't currently do anything, other than look for the id string so it knows which line in the config file to pass to ffmpeg.
Quote:
Originally Posted by hazel
But it is an error message after all, so actually I think it should go to standard error.
That's what my thinking was when I wrote that code - that's why I used fprintf and stderr.
Sorry that should be ffmpeg not fselect.sh. I was just playing with a test script and forget to change it when I posted the updated code. It's how execv works. It uses an array for the command line arguments and the first argument is always the command itself.
The string manipulating stuff is probably confusing and mainly used because I was using different string types.
I've just read the link about functions that ntubski posted before; while other than the part at the bottom about "variable-length argument lists", it seems to make sense; other than the "..." to indicate a "variable-length argument list"; I'm not really clear on much else about "variable-length argument lists".
Sorry, I was just looking at the example at the top. I didn't pay attention to the other stuff. I would not recommend learning about variable-length argument lists right now, it's an advanced topic that is seldom needed (you can generally use vararg functions like printf() without knowing the details of it).
Quote:
Originally Posted by rtmistler
And why must you use fprint() to stderr? I know it's valid, but boy I'd hate to have to deal with some odd occurrence where it is actually redirected somewhere else besides the console. Just use plain old printf(). Similarly you were using fputs() at one point too. When you're learning, why complicate things?
Sending error messages to stderr is standard practice:
Code:
$ cp a 2> /dev/null
$ cp a > /dev/null
cp: missing destination file operand after 'a'
Try 'cp --help' for more information.
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
So I read the man pages for the functions I mentioned before in michaelk's code above, and while some of it was a bit like "yeah ok, whatever that really means"; those functions do make at least a little more sense now, and therefore michaelk's code is at least a little easier to follow. I still haven't touched my program yet, as I've just been practising good old strcpy(). I wrote a little program just to try and get the hang of strcpy(), and while I think I understand it a lot better now, I have a few questions about it; why does it put all of the strings in s1[] if I declare my "test arrays" outside of the main function? But if I declare the array within the main function, it doesn't do that. Also, why does strcpy() expect you to declare an array size?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.