Problem doing an e-mail program in C

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mike Wahler

    #16
    Re: Specific problem...now you can help =)


    "tyler_durd en" <tom4_h4wk@hotm ail.com> wrote in message
    news:af31f4a0d7 c6982fd90996e0b 2c2df3d@localho st.talkaboutpro gramming.com...[color=blue]
    > So I should not use gets?
    > but I need the user to insert the from,to,subject and message...the
    > function of fgets is to get something from a file,right?[/color]

    From a stream. One of the standard streams is 'stdin'.
    Look it up.

    -Mike


    Comment

    • Flash Gordon

      #17
      Re: Specific problem...now you can help =)

      On Wed, 29 Dec 2004 17:37:20 -0500
      "tyler_durd en" <tom4_h4wk@hotm ail.com> wrote:
      [color=blue]
      > So I should not use gets?[/color]

      Definitely not. Ever.
      [color=blue]
      > but I need the user to insert the from,to,subject and message...the
      > function of fgets is to get something from a file,right?[/color]

      What do you think stdin is?
      [color=blue]
      > I thought of using scanf, but then if a space was inserted, it would
      > not keep the information correctly...[/color]

      Well, there are scan sets, but using fgets is the simplest solution if
      you want to read a line. Although you still have to be careful. The
      alternatives are reading a character at a time or using a library
      implemented by one of the regulars. However, using a third party library
      might upset your tutor.
      [color=blue]
      > in the "What I have until now" is all my program until this phase...
      > thanks a lot for your help..[/color]

      Well, we do help with C questions.
      --
      Flash Gordon
      Living in interesting times.
      Although my email address says spam, it is real and I read it.

      Comment

      • Robert B. Clark

        #18
        Re: What I have until now

        On Wed, 29 Dec 2004 16:36:41 -0500, "tyler_durd en"
        <tom4_h4wk@hotm ail.com> wrote:
        [color=blue]
        >ok..so what I did until now is this...
        >the main file is this one:
        >------------------------------(progmail.c)----
        >#include <stdio.h> /* para funcoes como printf, scanf, etc */
        >#include <stdlib.h> /* para a funcao exit */
        >#include <string.h> /* para funcoes relacionadas com strings */
        >#define DIMMAIN 20
        >
        >void comandom(void);
        >void comandoC(void);
        >void comandoL(void);[/color]

        The above declarations do not match the definitions you used later
        on--e.g., comandom() takes a pointer to MAIL as its sole argument, yet
        here you declare the function as taking no arguments.
        [color=blue]
        >
        >int help(){[/color]

        If you mean void, say so:

        int help(void)

        Actually, I fail to see why help returns an int. The return value seems
        to not be used elsewhere in your code. You could simply defined help as
        a void function:

        void help(void)

        and omitted the return 0 statement at the end of the function.

        <snip>
        [color=blue]
        >int main (){[/color]

        Again,

        int main(void)
        [color=blue]
        > char c;
        >
        > fopen("mail.txt ","r");[/color]

        You discarded the returned FILE pointer--why?

        Unless you planned to pass the FILE pointer to one of your comandox
        functions, I fail to see why you opened the file at all.
        [color=blue]
        > printf("E-mail program.\n");
        >
        >
        > do{
        > putchar ('&');
        > scanf("%s",&c);[/color]

        fgets would be a better choice for user input. You could write a
        function around fgets and make it general enough to use for a variety of
        user input.
        [color=blue]
        > switch (c)
        > {
        > case '?':help();brea k;[/color]
        <snip>[color=blue]
        > case 'm':comandom(); break;[/color]

        In your comandom.c file, you define comandom() as taking a pointer to
        MAIL. Here you omit the argument, and even if you hadn't, there is no
        definition in scope for the MAIL data type--unless you omitted this in
        your posted code.

        <snip>[color=blue]
        > case 'C':comandoC(); break;
        > case 'L':comandoL(); break;
        > default: printf("Unknown command!\n");br eak;
        > }[/color]

        See above comments about the comandox functions.

        Also, the default case would also be a good place to call your help()
        function.
        [color=blue]
        >
        > }while (c!='x');
        >
        > return 0;
        > }[/color]

        Use EXIT_SUCCESS or EXIT_FAILURE instead of 0.
        [color=blue]
        >my "m" command, which is supposed to ask you for the email informations is
        >this one:
        >----------------/comandom.c-----------
        >#include <stdio.h>
        >
        >typedef struct mail
        >{
        > char from[120];
        > char to[120];
        > char sub[120];
        > char msg[120];
        >} MAIL;[/color]

        DEFINEd macros would be a good choice instead of hard-coding these
        constants:

        #define MSG_MAX_FROM 120
        #define MSG_MAX_TO MSG_MAX_FROM
        #define MSG_MAX_SUB MSG_MAX_FROM
        #define MSG_MAX_MSG 1024
        // Did you really want only 120 chars for the message?

        typedef struct mail
        {
        char from[MSG_MAX_FROM];
        char to[MSG_MAX_TO];
        char sub[MSG_MAX_SUB];
        char msg[MSG_MAX_MSG];
        }
        MAIL;

        This data type should be accessible to all of your modules that require
        it, not just this one. I'd suggest placing it in a header file that
        your other modules can read.
        [color=blue]
        >void comandom(MAIL *ptr)
        >{
        > printf("From: \n"); gets(ptr->from);
        > printf("To: \n"); gets(ptr->to);
        > printf("Subject :\n"); gets(ptr->sub);
        > printf("Message :\n"); gets(ptr->msg);
        >}[/color]

        See comments about fgets.

        I'd assume that the MAIL pointer in this function would point to a MAIL
        object that already exists? Nowhere in your posted code is a MAIL
        object created.
        [color=blue]
        >------------------------------
        >
        >then I have the command "q" which when pressed has to keep all the written
        >emails in a mail.txt fuile..I made this:
        >--------------(comandoq.c)------------
        >#include <stdio.h>
        >[/color]
        There is no function here!

        I'm assuming you meant

        void comandoq(MAIL *ptr)
        {

        For that matter, void is a poor choice of return type for this function.
        More on this below.
        [color=blue]
        >FILE *fp;
        >
        >fp = fopen("mail.txt ","a");[/color]

        This needs error-checking. What if the system could not open or create
        mail.txt?
        [color=blue]
        >fprintf(fp,"Fr om:%s\n",from);
        >fprintf(fp,"To :%s\n",to);
        >fprintf(fp,"Su bject:%s\n",sub );
        >fprintf(fp,"Me ssage:%s\n",msg );
        >fprintf(fp,"\n ");[/color]

        Where are from, to, sub and msg? Are these supposed to be members of
        the MAIL data type that you neglected to pass as an argument to this
        function?
        [color=blue]
        >
        >fclose(fp);
        >
        >}[/color]

        If there had been an error opening the file, your code as written does
        not communicate that back to the caller. I'd suggest something more
        like

        #include <stdio.h>
        #define MAIL_FILE "mail.txt"

        int comandoq(MAIL *ptr)
        {
        FILE *fp;

        if ((fp = fopen(MAIL_FILE , "a")) != NULL)
        {
        fprintf(fp, "From: %s\n", ptr->from);
        fprintf(fp, "To: %s\n", ptr->to);
        //...
        fclose(fp);
        }
        else
        fprintf(stderr, "\aError opening %s!\n", MAIL_FILE);

        return fp != NULL; // Returns 0 if file error; true otherwise
        }
        [color=blue]
        >----------------
        >it's not complete so I woudl like you to help me, please.
        >the output of the mail.txt file has to be something like this:[/color]

        You're not kidding. The code you posted doesn't even compile. :)

        Try this: Focus on writing routines to read the mail data from the user
        and write it to a file. Make sure that you can append several emails to
        the file.

        When this is working cleanly, THEN proceed to the next step.

        Then, write a routine to read those emails from the file and display
        them to the user.

        The rest should come easily after this initial hurdle is passed.

        Keep in mind that some declarations need to be accessible to all of your
        modules--the MAIL data type, for one.
        [color=blue]
        >thanks a lot, help me please, it's a case of life or death =)[/color]

        Hope this helps.


        --
        Robert B. Clark (email ROT13'ed)
        Visit ClarkWehyr Enterprises On-Line at http://www.3clarks.com/ClarkWehyr/

        Comment

        • Robert B. Clark

          #19
          Re: Specific problem...now you can help =)

          On Wed, 29 Dec 2004 17:37:20 -0500, "tyler_durd en"
          <tom4_h4wk@hotm ail.com> wrote:
          [color=blue]
          >So I should not use gets?
          >but I need the user to insert the from,to,subject and message...the
          >function of fgets is to get something from a file,right?[/color]

          A stream, which is not necessarily a file. stdin can be a stream.

          Unlike gets, fgets can be told when to stop, preventing nasty buffer
          overflows that are possible with gets.

          -------
          fgets gets a string from a stream

          Declaration:
          char *fgets(char *s, int n, FILE *stream);

          fgets reads characters from a stream into the string s. It stops when
          it reads either n-1 characters or a newline character, whichever comes
          first.

          fgets retains the newline character at the end of s and appends a null
          byte to s to mark the end of the string.
          --------

          --
          Robert B. Clark (email ROT13'ed)
          Visit ClarkWehyr Enterprises On-Line at http://www.3clarks.com/ClarkWehyr/

          Comment

          • Barry Schwarz

            #20
            Re: Specific problem...now you can help =)

            On Wed, 29 Dec 2004 15:25:59 -0500, "tyler_durd en"
            <tom4_h4wk@hotm ail.com> wrote:
            [color=blue]
            >I made this command but it gives me a "segmentati on fault" error...can you
            >help me?[/color]

            C doesn't have commands. You wrote a function.
            [color=blue]
            >
            >-------------------------
            >
            >#include <stdio.h>
            >
            >typedef struct mail
            >{
            > char from[120];
            > char to[120];
            > char sub[120];
            > char msg[120];
            >} MAIL;
            >
            >void comandom(MAIL *ptr)
            >{
            > printf("From: \n"); gets(ptr->from);
            > printf("To: \n"); gets(ptr->to);
            > printf("Subject :\n"); gets(ptr->sub);
            > printf("Message :\n"); gets(ptr->msg);[/color]

            While using gets is undesirable, as long as you typed in short (<120)
            strings it did not cause the problem you are experiencing.[color=blue]
            >
            >
            >}[/color]
            You need to show us how you are calling this function.


            <<Remove the del for email>>

            Comment

            • Barry Schwarz

              #21
              Re: What I have until now

              On Wed, 29 Dec 2004 16:36:41 -0500, "tyler_durd en"
              <tom4_h4wk@hotm ail.com> wrote:
              [color=blue]
              >ok..so what I did until now is this...
              >the main file is this one:
              >------------------------------(progmail.c)----
              >#include <stdio.h> /* para funcoes como printf, scanf, etc */
              >#include <stdlib.h> /* para a funcao exit */
              >#include <string.h> /* para funcoes relacionadas com strings */
              >#define DIMMAIN 20
              >
              >void comandom(void);[/color]

              This prototype says the function has no parameters.

              snip[color=blue]
              >
              >void comandom(MAIL *ptr)[/color]

              This definition says the function has one parameter. When you lie to
              the compiler, you invoke undefined behavior.
              [color=blue]
              >{
              > printf("From: \n"); gets(ptr->from);
              > printf("To: \n"); gets(ptr->to);
              > printf("Subject :\n"); gets(ptr->sub);
              > printf("Message :\n"); gets(ptr->msg);
              >
              >
              >}
              >------------------------------[/color]
              snip


              <<Remove the del for email>>

              Comment

              • tyler_durden

                #22
                Re: What I have until now

                thanks a lot for all your help..I'm really appreciated...
                with all the help I've been getting in forums I've been able to continue
                my program and it's almost done, but I'm having a big problem that I
                believe is it's solved, the remaining stuff is easy...
                my full program until now is here:
                Latest news coverage, email, free stock quotes, live scores and video are just the beginning. Discover more every day at Yahoo!


                the problem is the segmentation fault when main trys to run
                leficheiro.c... . the *.c2 files are the functions I am working now...

                Comment

                Working...