strtok dumb question: how can this be failing? 
Author Message
 strtok dumb question: how can this be failing?

system is linux mandrake 8.2
this is very basic code and i am getting warnings
code runs but segmentation fault

main.c: In function `main':
main.c:40: warning: passing arg 1 of `fgets' from incompatible pointer
type
main.c:41: warning: passing arg 2 of `strtok' makes pointer from
integer without a cast
main.c:43: incompatible types in assignment

#include <stdio.h>
#include <stdlib.h> /* functions like abs() */
#include <fcntl.h> /* needed for open mode arguments */
#include <sys/stat.h> /* need for file status flags */
#include <sys/types.h> /* needed for file types */
#include <string.h>

#define DELIM '\n'
#define _BUFSIZ 1024

/* function prototypes
 */

int main(int argc, char **argv) {

        FILE    *svcs ;
        int     lines, len ;
        char * buf[_BUFSIZ];
        char * token[32];

        svcs = fopen("/usr/local/etc/svcs", "r");
                for (lines = 0; !feof(svcs) ; lines++) {
                        fgets(buf, _BUFSIZ, svcs);
                        token = (strtok(buf, '\n'))

                                printf("found \'\\n\'\n");
                                printf("buf[%d]:%s\n", lines, buf[lines]);
                                printf("debug: here\n");
                }
                fclose(svcs);

Quote:
} /* end main */

all i want to do is get the values in this file and put them in
variables so that i can test these services.  it seems that i can't
get beyond parsing the file with strtok.

should i use another method?
the file is in the following format:
# svcs
# list services here
sshd
named
sendmail
smbd
dhcpd
httpd
xinetd
crond



Mon, 14 Feb 2005 14:32:31 GMT  
 strtok dumb question: how can this be failing?

Quote:

> system is linux mandrake 8.2
> this is very basic code and i am getting warnings
> code runs but segmentation fault

Where do you want to post all this stuff?

Quote:

> main.c: In function `main':
> main.c:40: warning: passing arg 1 of `fgets' from incompatible pointer
> type
> main.c:41: warning: passing arg 2 of `strtok' makes pointer from
> integer without a cast
> main.c:43: incompatible types in assignment

> #include <stdio.h>
> #include <stdlib.h> /* functions like abs() */
> #include <fcntl.h> /* needed for open mode arguments */
> #include <sys/stat.h> /* need for file status flags */
> #include <sys/types.h> /* needed for file types */
> #include <string.h>

> #define DELIM '\n'
> #define _BUFSIZ 1024

> /* function prototypes
>  */

> int main(int argc, char **argv) {

>    FILE    *svcs ;
>    int     lines, len ;
>    char * buf[_BUFSIZ];
>    char * token[32];

>    svcs = fopen("/usr/local/etc/svcs", "r");
>            for (lines = 0; !feof(svcs) ; lines++) {
>                    fgets(buf, _BUFSIZ, svcs);

How is buf defined and what do you give fgets?
Hint: fgets takes a char * as first parameter

Quote:
>                    token = (strtok(buf, '\n'))

This is plain wrong strotks prototyp look like this
char *strtok(char *s, const char *delim)

As pointed out elsewere it does not make sense to use "\n"
as delimiter alone there will be just one in buf if fgets is
successfull. Nothing will get split.

Why don't you do yourself a favour and learn the differences between
char**, char*, char and *char[] ?

Why don't you try to understand in a simple example how strtok works?

Quote:

>                            printf("found \'\\n\'\n");
>                            printf("buf[%d]:%s\n", lines, buf[lines]);
>                            printf("debug: here\n");
>            }
>            fclose(svcs);

> } /* end main */

> all i want to do is get the values in this file and put them in
> variables so that i can test these services.  it seems that i can't
> get beyond parsing the file with strtok.

> should i use another method?

The way is quite ok, but you do not understand how
a) to read prototyps
b) to handle pointers

Quote:
> the file is in the following format:
> # svcs
> # list services here

Well I can't see any hint why strtok should be necessary. You can
eliminate it totally. what you want it fgets and probably strchr

Quote:
> sshd
> named
> sendmail
> smbd
> dhcpd
> httpd
> xinetd
> crond

Regards
Friedrich


Mon, 14 Feb 2005 15:23:20 GMT  
 strtok dumb question: how can this be failing?

Quote:

> system is linux mandrake 8.2
> this is very basic code and i am getting warnings
> code runs but segmentation fault

> main.c: In function `main':
> main.c:40: warning: passing arg 1 of `fgets' from incompatible pointer
> type
> main.c:41: warning: passing arg 2 of `strtok' makes pointer from
> integer without a cast
> main.c:43: incompatible types in assignment

> #include <stdio.h>
> #include <stdlib.h> /* functions like abs() */
> #include <fcntl.h> /* needed for open mode arguments */
> #include <sys/stat.h> /* need for file status flags */
> #include <sys/types.h> /* needed for file types */

You're not using any of the three headers above, and they're off-topic
for this newsgroup anyway, since they're not defined by the ISO C Standard.

Quote:
> #include <string.h>

> #define DELIM '\n'
> #define _BUFSIZ 1024

By using an initial underscore in this way, you're treading on
reserved namespace, and invoking undefined behavior.

- Show quoted text -

Quote:

> /* function prototypes
>  */

> int main(int argc, char **argv) {

>    FILE    *svcs ;
>    int     lines, len ;
>    char * buf[_BUFSIZ];
>    char * token[32];

>    svcs = fopen("/usr/local/etc/svcs", "r");
>            for (lines = 0; !feof(svcs) ; lines++) {
>                    fgets(buf, _BUFSIZ, svcs);
>                    token = (strtok(buf, '\n'))

>                            printf("found \'\\n\'\n");
>                            printf("buf[%d]:%s\n", lines, buf[lines]);
>                            printf("debug: here\n");
>            }
>            fclose(svcs);

> } /* end main */

Everything here is pretty broken. I think what you meant to do was to
store each line in a seperate element of an array. But that's not what
you do. You also fail completely to provide any safeguard checks to
ensure that you don't run out of space if the file has more lines than
you expected.

buf is the wrong type for how you use it in fgets() and strtok()
(strtok() seems ill-suited for the use to which you're putting it); it
might conceivably be the right type to hold _BUFSIZ (1024) lines of
text, but you're not allocating space for the lines themselves, if you
were trying to do that.

My suggestions:

  1. Make buf a char **.

  2. Allocate enough memory for buf to hold as many (char *)s as you
     expect you'll need:

        lines_in_buf = INITIAL_LINES;
        buf = malloc(lines_in_buf * sizeof (*buf));

  3. For each line, allocate enough space in the appropriate element
     of buf to hold as many characters as you expect you'll need:

        chars_in_line = INITIAL_CHARS;
        buf[current_line] = malloc(chars_in_line * sizeof (**buf));

  4. Read in a line using fgets(). If it didn't fit in
     buf[current_line] (i.e., buf[current_line] +
     strlen(buf[current_line]) - 1 != '\n'), then make more room in
     the line:

        current_write_pos = strlen(buf[current_line]);
        chars_in_line += ADD_CHARS_SIZE;
        temp_line = realloc(buf[current_line], chars_in_line);

     Assigning buf[current_line] = temp_ptr once you've made sure it
     was successful, and try another fgets() from buf[current_line] +
     current_write_pos. Repeat as necessary.

  5. Ditch the strtok(), and remove newlines like:

        buf[current_line] + strlen(buf[current_line]) - 1 = '\0';

  6. If there ends up being more lines than you thought, expand buf as
     necessary:

        lines_in_buf += ADD_LINES_SIZE;
        temp_buf = realloc(buf, lines_in_buf * sizeof(*buf));

...but first, you should probably get a copy of K&R2 (if you don't
already have one), and get some refreshers in C. There are some
thinkos in your code, particularly in your choice of types, that
suggest you might be able to use them.

-Micah



Mon, 14 Feb 2005 17:37:13 GMT  
 strtok dumb question: how can this be failing?

Quote:

> system is linux mandrake 8.2
> this is very basic code and i am getting warnings
> code runs but segmentation fault

> main.c: In function `main':
> main.c:40: warning: passing arg 1 of `fgets' from incompatible pointer
> type
> main.c:41: warning: passing arg 2 of `strtok' makes pointer from
> integer without a cast
> main.c:43: incompatible types in assignment

> #include <stdio.h>
> #include <stdlib.h> /* functions like abs() */
> #include <fcntl.h> /* needed for open mode arguments */
> #include <sys/stat.h> /* need for file status flags */
> #include <sys/types.h> /* needed for file types */

The 3 header files above -- fcntl.h, sys/stat.h, and sys/types.h
are NOT Standard C.  Incidentally, from browsing your code below,
I can't find one instance where you need these headers.

Quote:
> #include <string.h>

> #define DELIM '\n'
> #define _BUFSIZ 1024

The underscore here invades implementation namespace.  Use
  #define BUFSIZ 1024
instead.

Quote:

> /* function prototypes
>  */

> int main(int argc, char **argv) {

>    FILE    *svcs ;
>    int     lines, len ;
>    char * buf[_BUFSIZ];

This is an array of pointers to char.  Is this really what you want?

Quote:
>    char * token[32];

Again, an array of pointers to char.  Really what you want?

Quote:

>    svcs = fopen("/usr/local/etc/svcs", "r");
>            for (lines = 0; !feof(svcs) ; lines++) {

See the FAQ about using feof() to control a loop like this.  It
doesn't work the way you expect it to work.  feof() will
only return true *after* fgets() has reached EOF and returned NULL.
Thus, your loop will iterate one more time than you want it to.

Quote:
>                    fgets(buf, _BUFSIZ, svcs);

Here, buf decays to a char **.  fgets wants a char * as its
first parameter.  This explains your "main.c 40" warning, which
incidentally should be an error.

Quote:
>                    token = (strtok(buf, '\n'))

Same comment here.  buf decays to a char **.  strtok expects a char *.
Also, for the second parameter, strtok expects a char *.  You pass it
a char.  Use "\n" instead of '\n'.  This explains your "main.c 41" warning,
which should also be an error.  (I don't like your compiler so far).

Another recommendation here: If you ever run your program on Windows/DOS
systems, you may find that your strtok doesn't work, since Microsoft
likes to use a \r\v combination to mean \n.  Thus, a slightly better
(and probably more portable) strtok call would be:

    token = strtok(buf, "\r\v\n");

Cheers,
Matt



Mon, 14 Feb 2005 21:35:24 GMT  
 strtok dumb question: how can this be failing?

Quote:

>system is linux mandrake 8.2
>this is very basic code and i am getting warnings
>code runs but segmentation fault

I'm not surprised

Quote:
>main.c: In function `main':
>main.c:40: warning: passing arg 1 of `fgets' from incompatible pointer
>type
>main.c:41: warning: passing arg 2 of `strtok' makes pointer from
>integer without a cast
>main.c:43: incompatible types in assignment

Read the blasted error messages, check what types the functions
require, and then pass the RIGHT TYPES.

BTW I think you have a serious misunderstanding about arrays and
pointers.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>



Tue, 15 Feb 2005 05:37:56 GMT  
 strtok dumb question: how can this be failing?

Quote:

>Another recommendation here: If you ever run your program on Windows/DOS
>systems, you may find that your strtok doesn't work, since Microsoft
>likes to use a \r\v combination to mean \n.  

I don't know what makes you think this, but its completely wrong.
Windows and DOS behave quite correctly in this respect. \v is not even
an escape sequence. I've got about a zillion Windows/dos apps which
use strtok and they work fine with \n
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>


Tue, 15 Feb 2005 05:40:07 GMT  
 strtok dumb question: how can this be failing?


Wed, 18 Jun 1902 08:00:00 GMT  
 strtok dumb question: how can this be failing?

Quote:


> My suggestions:

>   1. Make buf a char **.

>   2. Allocate enough memory for buf to hold as many (char *)s as you
>      expect you'll need:

>         lines_in_buf = INITIAL_LINES;
>         buf = malloc(lines_in_buf * sizeof (*buf));

>   3. For each line, allocate enough space in the appropriate element
>      of buf to hold as many characters as you expect you'll need:

>         chars_in_line = INITIAL_CHARS;
>         buf[current_line] = malloc(chars_in_line * sizeof (**buf));

>   4. Read in a line using fgets(). If it didn't fit in
>      buf[current_line] (i.e., buf[current_line] +
>      strlen(buf[current_line]) - 1 != '\n'), then make more room in
>      the line:

>         current_write_pos = strlen(buf[current_line]);
>         chars_in_line += ADD_CHARS_SIZE;
>         temp_line = realloc(buf[current_line], chars_in_line);

>      Assigning buf[current_line] = temp_ptr once you've made sure it
>      was successful, and try another fgets() from buf[current_line] +
>      current_write_pos. Repeat as necessary.

>   5. Ditch the strtok(), and remove newlines like:

>         buf[current_line] + strlen(buf[current_line]) - 1 = '\0';

>   6. If there ends up being more lines than you thought, expand buf as
>      necessary:

>         lines_in_buf += ADD_LINES_SIZE;
>         temp_buf = realloc(buf, lines_in_buf * sizeof(*buf));

> ...but first, you should probably get a copy of K&R2 (if you don't
> already have one), and get some refreshers in C. There are some
> thinkos in your code, particularly in your choice of types, that
> suggest you might be able to use them.

> -Micah

thanks for teaching me how to do this
BTW is there a program out there which would translate Bash shell
scripting into C Language?  i really would like to improve my C and
would like to do it by converting the tools i've created in Bash into
C programs.

does anyone know of such a tool?



Tue, 15 Feb 2005 15:06:18 GMT  
 strtok dumb question: how can this be failing?

Quote:

> thanks for teaching me how to do this
> BTW is there a program out there which would translate
> Bash shell scripting into C Language?  i really would
> like to improve my C and would like to do it by
> converting the tools i've created in Bash into C
> programs.

Source code produced by an automated tool is usually of dubious quality. I
wouldn't recommend trying to improve your C in that way.

--
Simon.



Wed, 23 Feb 2005 22:16:09 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Am I dumb?

2. ifstream won't work or am i dumb

3. Dumb, Dumber and Me. Classes Help Please!

4. Am I failed ?!

5. Dumb MDAC question

6. Dumb Question about showing results in a text box

7. Dumb Fread Question

8. Dumb question re: stack overflow

9. Dumb question?

10. Dumb Question

11. Novice with dumb question

12. Two dumb questions

 

 
Powered by phpBB® Forum Software