LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Tried to write something "serious" and have failed once again (https://www.linuxquestions.org/questions/programming-9/tried-to-write-something-serious-and-have-failed-once-again-4175657546/)

hazel 07-18-2019 06:37 AM

I agree that gcc error/warning messages are exceedingly cryptic. I mean, for example "Assignment makes x out of y without a cast". What does that mean? It took me some time to learn that it actually means "Type mismatch: you are trying to store a value of type y in a variable of type x". So why can't it say that? Also I had to learn that weird messages about assembly code actually indicate an unpaired opening or closing brace. Again, why so obscure? This is a particular beef of mine because I like clarity in instructions.

Remember that a genuine error prevents an instruction from compiling at all. gcc will just drop it and this will cause further errors downstream. So always scroll back to the first error and fix that. Then recompile, and you may find that the others have vanished. Warnings don't prevent an instruction from compiling but they do indicate that gcc wasn't sure exactly what you meant and might have translated the code wrongly, so if it's your code, you should fix them.

jsbjsb001 07-18-2019 08:15 AM

Quote:

Originally Posted by rtmistler (Post 6016166)
All I have here is to advise you to get fundamental.

Read that syntax error and see what it means.

"A variable has a problem because it is the first time it has been seen in this function."

Period.

These types of syntax errors are things which you need to be able to fix.

I'm very surprised if you haven't seen numerous ones just like this during your last 8 months of experimenting with C code.

If you need to have a reliance on someone telling you exactly what to change here, then I'm afraid that I can not provide much assistance at this point, for these small syntax issues.

I have tried reading the error messages, I've tried several times to read the bloody thing. I've tried several different things in the functions parameters (not sure that's the right word, what's after the function name in it's header anyway) and no matter what I do, it still gives me errors and/or warnings. And it's still not clear to me why it's giving me the messages.

I would fix them if I knew why it was giving the messages to begin with, but again, I don't know why what I've done is wrong.

I've probably seen every error/warning message gcc has to offer, it doesn't mean I understood what it/they meant, and/or why I was getting them in the first place. There's been many times now where I'm not even sure what I changed that made said message(s) go away.

The whole point of my question was so I don't need any "reliance" on others to understand any more such messages. But clearly I'm too stupid to understand why things aren't working. So I guess I was right in thinking even bothering to continue with this was a bad idea. So call me a quitter, but it looks like I'm done.

Quote:

Originally Posted by hazel (Post 6016185)
I agree that gcc error/warning messages are exceedingly cryptic. I mean, for example "Assignment makes x out of y without a cast". What does that mean? It took me some time to learn that it actually means "Type mismatch: you are trying to store a value of type y in a variable of type x". So why can't it say that? Also I had to learn that weird messages about assembly code actually indicate an unpaired opening or closing brace. Again, why so obscure? This is a particular beef of mine because I like clarity in instructions.

Remember that a genuine error prevents an instruction from compiling at all. gcc will just drop it and this will cause further errors downstream. So always scroll back to the first error and fix that. Then recompile, and you may find that the others have vanished. Warnings don't prevent an instruction from compiling but they do indicate that gcc wasn't sure exactly what you meant and might have translated the code wrongly, so if it's your code, you should fix them.

Thank you Hazel. Yes, I would have to agree with you. And your explanation of "Assignment makes x out of y without a cast" makes a hell of a lot more sense than the message gcc gives you. So at least that makes far more sense to me now. Not that matters anyway, but still, and thanks again.

To save anyone any hassle and while it doesn't look like I'll be able to finish the program anyway; I'll mark this thread as [SOLVED].

Thanks for all the help.

ntubski 07-18-2019 08:21 AM

Quote:

Originally Posted by jsbjsb001 (Post 6016091)
Could someone just explain clearly and in really simple terms, what I'm doing wrong/missing

You're trying combine broken parts into a whole program and expecting it to work.


Quote:

and how I'm supposed to fix it?
You should start by writing simple programs which work correctly. Don't just copy-paste in snippets of code that other people posted.


Quote:

I'm trying to write a program that will look at a config file, then based on the first command-line argument entered, it will look for the relevant line in said config file, will read then rest of that same line for the relevant options for ffmpeg, then run ffmpeg with those arguments. So for example, I type in: ffcliFront (the name of my non-working program) mp3 <inputfile name for ffmpeg here> it will then run ffmpeg with the command line arguments in the config file AFTER the "mp3" in that example, and NOT including the "mp3".
Write a program which prints each line of a hard-coded file name. (the program should not take any arguments)

Write a program which prints the "mp3" line of a hard-coded file name, or an error message if there is no such line.

Write a program which finds and saves the "mp3" line into a variable, and then prints it (same behaviour as previous program, but restructured internally for better reuse).

Write a program which executes ffmpeg with a sequence of hard-coded arguments. (the program should not take any arguments, nor read any files)

Write a program that checks the command line arguments, and prints them out as parsed (but don't open any files, or execute any programs). E.g.,
Code:

$ ffcliArgs mp3 input-file.txt
File type arg = mp3
Input file name = input-file.txt


After doing all that, you should be ready to combine what you've into a program that does what you want.

hazel 07-18-2019 08:28 AM

Well, here's a funny thing! I took the code from the first post, pasted it into a file and ran gcc on it, and it compiled without errors. Of course I can't actually run the program because I don't have any configuration files for it to read.

rtmistler 07-18-2019 08:51 AM

Hazel has a perfect point about compiler errors and warnings. Start at the first instance, fix that, and retry the compilation.

Recommend you also heed what ntubski has said about how to proceed with coding.

Not for nothing, but you are exasperating about this, when my point is that you've been coding in C for about 8 months. If you wrote the traditional hello_world.c as follows:
Code:

void main(void)
{
    printf("Hello World!\n");
}

And you compiled it just using: gcc hello.c

You get this:
Code:

hello.c: In function ‘main’:
hello.c:3:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
    printf("Hello World!\n");
    ^~~~~~
hello.c:3:5: warning: incompatible implicit declaration of built-in function ‘printf’
hello.c:3:5: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’

Now ...

Are you telling me that you do not know how to fix this?!? I feel that you absolutely can fix that.

Similarly when the compiler tells you, (completely paraphrased) "I've never seen that variable before in my life ...", it's telling you that the variable you've attempted to use is not part of the function where you tried to use it.

Once again, here's your error:
Code:

ffcliFront.c: In function ‘readConfigFile’:
ffcliFront.c:47:21: error: ‘ffFormatID’ undeclared (first use in this function)
        while(fgets(ffFormatID, 128, configfile) != EOF) {

Figure out WHERE ffFormatID IS defined, or figure out if you typed the name incorrectly on this line.

Many here can do that for you, but how will you learn to do it for the next time? Really, we're not trying to be jerks, and we're not trying to stand over you in judgement and act superior. Just trying to make you think, as well as trying to get you to follow logical processes here.

hazel 07-18-2019 09:05 AM

Quote:

Originally Posted by rtmistler (Post 6016234)
If you wrote the traditional hello_world.c as follows:
Code:

void main(void)
{
    printf("Hello World!\n");
}

And you compiled it just using: gcc hello.c

You get this:
Code:

hello.c: In function ‘main’:
hello.c:3:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
    printf("Hello World!\n");
    ^~~~~~
hello.c:3:5: warning: incompatible implicit declaration of built-in function ‘printf’
hello.c:3:5: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’


Which proves the point I made earlier. How is an inexperienced programmer supposed to know what "implicit declaration" means? It should say something like "Function 'printf' not defined". Then it would be obvious that a header has been missed out. And I find the second warning even weirder. Because, even though the stdio.h header has not been included, gcc somehow seems to know all about this function, where the declaration should be found and that it is supposed to return an integer and not void.

rtmistler 07-18-2019 09:38 AM

Quote:

Originally Posted by hazel (Post 6016244)
Which proves the point I made earlier. How is an inexperienced programmer supposed to know what "implicit declaration" means? It should say something like "Function 'printf' not defined". Then it would be obvious that a header has been missed out. And I find the second warning even weirder. Because, even though the stdio.h header has not been included, gcc somehow seems to know all about this function, where the declaration should be found and that it is supposed to return an integer and not void.

Well, web search that topic. It's related, but an extension of the primary topic here. Warnings are far better than they used to be, by the way, and it's a tough topic.

That warning illustrated is patently obvious, it literally tells one to include <stdio.h>, whether or not you approve of the verbiage is a different story. Many years ago, you'd never see anything, anywhere near as verbose as that.

jsbjsb001 07-18-2019 11:58 AM

While I see what you're saying ntubski, and I appreciate you taking the time to help; I basically have done that for the very most part. Like for example; written code that just opens a file and displays it's contents, among other things (by themselves, without trying to do anything else). Doing stuff like that by itself seems easy enough, and does make sense. But like I was saying before; it's trying to "put it all together" that's proving impossible. That's why I commented out the program's second function, to just focus on at least getting something into the array from the file. I only copy and pasted what RT suggested, to try and follow his advice about printing the file content line by line, and going from there, before trying get my program to execute ffmpeg itself, and then pass the relevant args from the config file to ffmpeg itself. Like I said before; I've googled, and googled, and googled, I've looked at more sites about the errors I'm getting than I care to remember, and I'm still going um? ah? what the f*** are they talking about???!! Let alone trying to understand a wall of someone else's code.

Since Hazel said it compiled for her, I had another look at the code, and it seems I forgot to uncomment the array declaration, so I tried again to compile it, and yet again, I get yet another warning from gcc;

Code:

[james@jamespc ffcliFront]$ gcc -g -Wall -Werror ffcliFront.c -o ffcliFront
ffcliFront.c: In function ‘readConfigFile’:
ffcliFront.c:47:50: error: comparison between pointer and integer [-Werror]
        while(fgets(ffFormatID, 128, configfile) != EOF) {
                                                  ^
cc1: all warnings being treated as errors

Again, why my program seems to be trying to compare an integer and pointer, I have no idea. Which goes back to what Hazel was saying, and since I think she has said it the best:

Quote:

Originally Posted by hazel (Post 6016244)
Which proves the point I made earlier. How is an inexperienced programmer supposed to know what "implicit declaration" means? It should say something like "Function 'printf' not defined". Then it would be obvious that a header has been missed out. And I find the second warning even weirder. Because, even though the stdio.h header has not been included, gcc somehow seems to know all about this function, where the declaration should be found and that it is supposed to return an integer and not void.

I wish I knew, I don't know either - good question.

The bottom line is: as much as it would be nice to be able to write, well ANYTHING useful, or even just semi-useful... I just don't have the patience to keep sitting here going Um? Ah? What the f*** is it talking about??! I have no f'ing idea why it's saying that/doing that/whatever!! So perhaps I'm better off just using other people's software instead. Even with non-programming related problems there's almost always been some kind of clue, even just as to what the problem even just MIGHT be, whereas this, it's once again like trying to put together a jigsaw puzzle blindfolded. I'm sorry, I just don't know what the problem even might be, and knowing what line it's on doesn't help much when you just don't have the skills to be able to see it. I'm not blaming anyone here for that BTW either, I guess my learning style just isn't compatible with learning programming, or at least getting beyond just adding a few numbers together, or just printing stuff to the screen. I can use a calculator and the echo command for those things, so what's the point in coding it? none.

PS: The above isn't intended as a rant. I wasn't trying to be rude to anyone, it's just getting beyond a joke not being able to understand where I'm going wrong, and how to fix it. Sorry if I was rude - not intended on my part.

hazel 07-18-2019 12:38 PM

Quote:

Originally Posted by jsbjsb001 (Post 6016329)
Since Hazel said it compiled for her, I had another look at the code, and it seems I forgot to uncomment the array declaration, so I tried again to compile it, and yet again, I get yet another warning from gcc;

The code I compiled came from your first post, so it was different from the one you are now using.
Quote:

Code:

[james@jamespc ffcliFront]$ gcc -g -Wall -Werror ffcliFront.c -o ffcliFront
ffcliFront.c: In function ‘readConfigFile’:
ffcliFront.c:47:50: error: comparison between pointer and integer [-Werror]
        while(fgets(ffFormatID, 128, configfile) != EOF) {
                                                  ^
cc1: all warnings being treated as errors

Again, why my program seems to be trying to compare an integer and pointer, I have no idea.
That's easy. fgets returns a pointer pointing to a string read from a file. EOF is a named integer constant, which usually has a value of -1 (although with named constants you don't need to know the actual value). Therefore they cannot be compared. I suspect you have got fgets confused with fgetc, which returns a character.

rtmistler 07-18-2019 12:51 PM

With your recent correction for the variable, the error you now see was begat from my example which was stated as not compiled, or tested. Therefore sorry that it actually did have a syntax error, it was not advertised to have been tested at all.

Here is how to diagnose:
It is complaining that there's a disagreement between the result from fgets() and EOF.

First question I ask myself is "What is fgets() expecting?"

Man page says that the return values from fgets() is defined as:
gets() and fgets() return s on success, and NULL on error or when end of file occurs while no characters have been read.

The test should have been for NULL.

Guarantee that this is where I made the mental error:
Earlier in the man page for fgets() it states:
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte (aq\0aq) is stored after the last character in the buffer.

So I saw EOF and put that in as the test outcome.

Had I tried a compile and test, it would've told me the same error and I'd have correct that to be NULL.

ntubski 07-18-2019 07:40 PM

Quote:

Originally Posted by jsbjsb001 (Post 6016329)
I basically have done that for the very most part. Like for example; written code that just opens a file and displays it's contents, among other things (by themselves, without trying to do anything else). Doing stuff like that by itself seems easy enough, and does make sense. But like I was saying before; it's trying to "put it all together" that's proving impossible. That's why I commented out the program's second function, to just focus on at least getting something into the array from the file.

Have you tried just printing the line of interest from the file?

jsbjsb001 07-18-2019 11:52 PM

So I changed EOF to NULL, and while it finally did print the lines in the config file, but it's not finding the line with the arg in front of it specified to my program on the command-line. It's not even giving me any error or warning messages when compiling it, so again, it's simply not obvious to me what the problem is. I've tried putting the line for strstr() inside the if statement, inside the while loop, outside of both, it prints everything. I tried the function parameters RT suggested, and I still get an error from gcc and then it refuses to compile it. I don't know why it's saying that, I don't even understand why RT even suggested what he did for. I tried what I had there before, and it just prints everything. Again, I have absolutely no idea what the problem is. To you guys it's obvious, to me, gcc for one may as well be saying "blah, blah, blah" - I don't know. I cannot understand what any Google results even mean. At least with non-programming related problems you can usually find something that says; "do this, and then this, and if XXXX is true, then the problem is YYYY". So again, I don't mean to be rude to anyone, but it's just hopeless - I have no idea what the problem is, sorry.

FWIW, and while it doesn't look like I'm ever going to understand this, here's the error I get with RT's suggested function parameters;

Code:

[james@jamespc ffcliFront]$ gcc -g -Wall -Werror ffcliFront.c -o ffcliFront
ffcliFront.c: In function ‘readConfigFile’:
ffcliFront.c:34:29: error: ‘argv’ undeclared (first use in this function)
    if ( (inputfile = fopen(argv[2], "r")) == NULL ) {
                            ^
ffcliFront.c:34:29: note: each undeclared identifier is reported only once for each function it appears in

(and yes, I can see what it's saying, but I don't know WHY it's saying that, I DID pass argv[2] TO the bloody thing)

And here's the config file content;

Code:

test ffmpeg ehe te teyeyyes y eye yeh eyh eeee  eyeye e ey
hdhshedhds

hseshhse

esehgshee

eseghshehsegh
eghs
esh
hes
esh
sehshe
she

Here's the code I currently have;

Code:

char readConfigFile(char *argv[]);
//char readConfigFile(char *filename, char *formatID);
//char execFfmpeg(char *argv[], char ffcmdline[]);

// includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

// main function
int main(int argc, char *argv[]) {
 
    if ( argc != 3 ) {
      fprintf (stderr, "Missing option or filename\n");
      return 1;
    }
         
    readConfigFile(argv);
    //readConfigFile(argv[1], argv[2]);

    return 0;
   
}

//char readConfigFile(char *filename, char *formatID) {
char readConfigFile(char *argv[]) {

    char ffFormatID[128];
    //char ffcmdline[100];
   
    // read input file
    FILE *inputfile;
       
    if ( (inputfile = fopen(argv[2], "r")) == NULL ) {
      fprintf(stderr, "File not found, exiting.\n");
      return 1;       
    }
    fclose(inputfile);
     
    // read config file
    FILE *configfile;
     
      if ( (configfile = fopen("config.conf", "r")) == NULL ) {
      fprintf(stderr, "Configuration file not found, exiting.\n");
      return 1;       
    }
 
    if( (configfile = fopen("config.conf", "r")) != NULL) {
        while( fgets(ffFormatID, 128, configfile ) != NULL) {
              printf("Line from config file: %s\n", ffFormatID);
              if( (strstr(ffFormatID, argv[1]) ) != NULL) {
                printf("Found string: %s\n", ffFormatID);
              }
        }
        fclose(configfile);
    }
       
    // pass char array with ffmpeg args & call execFfmpeg() fuction with args from config file
  // execFfmpeg(argv, ffcmdline);
 
    return 0;
}     

//char execFfmpeg(char *argv[], char ffcmdline[]) {
 
    //char* ffcmdargs[100]; 
   
    //printf("%s\n", ffcmdline);
    //strcpy(ffcmdargs,ffFormatID);
    // run fmpeg with args from config file & filename supplied to this program.
    // execv ("/usr/bin/ffmpeg", argv[2], ffFormatID);
       
    //return 0;
//}

(the above does compile without any errors or warnings, and does print out the file content, but does not find the arg at the beginning of the first line specified to the program, being "test")

Quote:

Originally Posted by ntubski (Post 6016476)
Have you tried just printing the line of interest from the file?

Yes, and while it seemed to work before (how I don't know), it's not doing it now.

rtmistler 07-19-2019 05:48 AM

Just before the strstr() call, print out argv[1] - Still valid, but I see what you've done to cause yourself this grief. Similarly, anyone can cause this grief, as I demonstrated by the incorrect guess code example using EOF when it should've been NULL.

EDIT:
Well, my initial read was that you were using argv[1] but given the shown prototype for readConfigFile which is commented out, it shows that filename is first, thus argv[1], and fformatID is second, thus argv[2].

And that's how you called it when you broke out argv[1] and argv[2] and passed them as strings.

BUT, when you use straight argv as the passing argument, you use argv[2] to choose and open your input file, and you use argv[1] as the search string.

So:
  1. You're correct that it compiles
  2. It in fact WORKS, the exact way it is constituted
  3. HOWEVER, you MUST call the main program from the command line with the following usage: program_name [format-id-string] [input-filename]
  4. I feel that your intended argument list was to put the [input-filename] first, but you've swapped how you treat argv[1] and argv[2]
  5. You don't have this problem with config.conf, because that filename is absolutely known, no question, it is hard-coded.
  6. One suggestion is to review what you've written in greater detail, but you seem to not be able to do that and reach any conclusions.
  7. Another suggestion would be to no longer use program arguments, until such time that you no longer make mistakes with them that you cannot seem to debug. Instead get the primary thing working, use two known file names and a known search string, get all that working, and then try to make it so that you can pass in arguments to use different names.

ntubski 07-20-2019 12:21 AM

Quote:

Originally Posted by jsbjsb001 (Post 6016527)
Code:

ffcliFront.c:34:29: error: ‘argv’ undeclared (first use in this function)
    if ( (inputfile = fopen(argv[2], "r")) == NULL ) {
                            ^
ffcliFront.c:34:29: note: each undeclared identifier is reported only once for each function it appears in

(and yes, I can see what it's saying, but I don't know WHY it's saying that, I DID pass argv[2] TO the bloody thing)

Okay, it sounds like you haven't really understood how scope and/or function arguments work yet. As a simpler example, see https://en.wikibooks.org/wiki/C_Prog..._and_functions, notice that the abs() function parameter is named x, and main() has variable with named x and another named y. Both can be passed to the abs() function. The name x in main() has no effect on the name x in abs().

Try renaming the variables in that program, and see which occurrences need to be changed in order to compile.


Quote:

Originally Posted by rtmistler (Post 6016595)
7. Another suggestion would be to no longer use program arguments, until such time that you no longer make mistakes with them that you cannot seem to debug. Instead get the primary thing working, use two known file names and a known search string, get all that working, and then try to make it so that you can pass in arguments to use different names.

+1 to that.

jsbjsb001 07-20-2019 07:08 AM

Quote:

Originally Posted by rtmistler (Post 6016595)
Just before the strstr() call, print out argv[1] - Still valid, but I see what you've done to cause yourself this grief. Similarly, anyone can cause this grief, as I demonstrated by the incorrect guess code example using EOF when it should've been NULL.

EDIT:
Well, my initial read was that you were using argv[1] but given the shown prototype for readConfigFile which is commented out, it shows that filename is first, thus argv[1], and fformatID is second, thus argv[2].

And that's how you called it when you broke out argv[1] and argv[2] and passed them as strings.

BUT, when you use straight argv as the passing argument, you use argv[2] to choose and open your input file, and you use argv[1] as the search string.

So:
  1. You're correct that it compiles
  2. It in fact WORKS, the exact way it is constituted
  3. HOWEVER, you MUST call the main program from the command line with the following usage: program_name [format-id-string] [input-filename]
  4. I feel that your intended argument list was to put the [input-filename] first, but you've swapped how you treat argv[1] and argv[2]
  5. You don't have this problem with config.conf, because that filename is absolutely known, no question, it is hard-coded.
  6. One suggestion is to review what you've written in greater detail, but you seem to not be able to do that and reach any conclusions.
  7. Another suggestion would be to no longer use program arguments, until such time that you no longer make mistakes with them that you cannot seem to debug. Instead get the primary thing working, use two known file names and a known search string, get all that working, and then try to make it so that you can pass in arguments to use different names.

Since people are still responding to this thread, and I must be insane for continuing trying to learn C; I've unmarked it as [SOLVED], and obviously the program isn't fully working yet.

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. Just to be clear; yes I was intending that you call the program with <program_name> [format-id-string] [input filename], rather the filename first - so yes, that was what I intended. But of course there's still the issue for one thing, of getting the "found" string into an array without the "identifier" being included as well, etc.

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.

Thank you for "bearing with me" RT. :)

Yes ntubski, I think you're probably right, so I'll have a read of the link you posted. Thanks again for your help!


All times are GMT -5. The time now is 03:43 AM.