Thread: fprintf in structure and list...

  1. #1
    Registered User
    Join Date
    Dec 2013
    Posts
    23

    fprintf in structure and list...

    Hello ,

    I have a problem with code:
    Code:
    struct sth {
    char* str;
    } pt;
    
    int fun() {
        FILE* siala;                                              
        char path[100] = {"sialac.txt"};
        if((siala = fopen(path, "a+")) == NULL)
        {
           puts ("ERROR.\n");
           exit(EXIT_FAILURE);
        }
    
    
    	int k, len;
    	
    		do {
    			pt.str = malloc(20 * sizeof(char));                     
    			printf("TYPE: ");
    			scanf("%s", pt.str);
    			fgets(pt.str, 20, stdin);
    			len = strlen(pt.str);
    			if((pt.str[len-1]) == '\n')
      			pt.str[len-1]='\0';
    			for(k=0; k < strlen(pt.str)-1; k++) {
    			if(!isalpha(pt.str[k])) break;
    			}
    			 if(k == strlen(pt.str)) break;
    		}
    		while(1);
    
    fprintf(siala, "\n%s", pt.str);
    }
    fprintf does not save string to file. What is wrong?

    And another question. How can I put structure into list?

    Thank you for your help!

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    There is no way that k can ever be equal to strlen(pt.str) after that for loop. So the do/while(1) is an infinite loop, and the fprintf() statement is never reached (and the function never returns either).

    Your code doesn't implement any list, so there is no way to put a structure into one.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User
    Join Date
    Dec 2013
    Posts
    23
    Quote Originally Posted by grumpy View Post
    There is no way that k can ever be equal to strlen(pt.str) after that for loop. So the do/while(1) is an infinite loop, and the fprintf() statement is never reached (and the function never returns either).

    Your code doesn't implement any list, so there is no way to put a structure into one.
    But when I delete
    Code:
     if(k == strlen(pt.str)) break;
    program always asks for type, whatever I type.

    How to fix this code?

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The maximum value that k can reach in that for loop is strlen(pt.str)-1 (and that's assuming all characters in the string are alphabetic). Therefore k can never be equal to strlen(pt.str). Ever.

    If you're getting a different result, that means the code you posted is not the code you're compiling/linking/running. Nobody here can advise you how to fix your code, since you haven't shown it. Forum members are not mind readers.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    Dec 2013
    Posts
    23
    Quote Originally Posted by grumpy View Post
    The maximum value that k can reach in that for loop is strlen(pt.str)-1 (and that's assuming all characters in the string are alphabetic). Therefore k can never be equal to strlen(pt.str). Ever.

    If you're getting a different result, that means the code you posted is not the code you're compiling/linking/running. Nobody here can advise you how to fix your code, since you haven't shown it. Forum members are not mind readers.
    I sent you a PM.

  6. #6
    Registered User
    Join Date
    Dec 2013
    Posts
    23
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    struct siala {
    char* a;
    char* b;
    int c;
    double d;
    char* e;
    char* f;
    char* g;
    } pt;
    
    
     typedef struct list {
     struct siala l;
     struct list * n;
     } *LISTF;
    
    
    void adt() {
        
        LISTF p = NULL;
        LISTF e;
           while (e->n != NULL) e = e->n;
           e = (LISTF) malloc(sizeof(LISTF));
        e->n = NULL;
        if(!p) p=e;
        
        FILE* filet;
        char path[100] = {"filet.txt"};
        if((filet = fopen(path, "a+")) == NULL)
        {
           puts ("ERROR.\n");
           exit(EXIT_FAILURE);
        }
        
        int k, len;
        
            do {
                pt.a = malloc(20 * sizeof(char));                       
                printf("TYPE: ");
                scanf("%s", pt.a);
                fgets(pt.a, 20, stdin);
                len = strlen(pt.a);
                if((pt.a[len-1]) == '\n')
                  pt.a[len-1]='\0';
                for(k=0; k < strlen(pt.a)-1; k++) {
                if(!isalpha(pt.a[k])) break;
                }
                 if(k == strlen(pt.a)) break;
            }
            while(1);
        
            do {
                pt.b = malloc(40 * sizeof(char));                       
                printf("TYPE: ");
                scanf("%s", pt.b);
                fgets(pt.b, 40, stdin);
                len = strlen(pt.b);
                if((pt.b[len-1]) == '\n')
                  pt.b[len-1]='\0';
                for(k=0; k < strlen(pt.b)-1; k++) {
                if(!isalpha(pt.b[k])) break;
                }
                 if(k == strlen(pt.b)) break;
            }
            while(1);
    
    
            do {    
                printf("TYPE ");                             
                scanf("%d", &pt.c);
            } while(pt.c < 0);
    
    
            do {
                printf("TYPE: ");               
                scanf("%lf", &pt.d);
            } while(pt.d < 0);
        
            do {
                pt.e = malloc(20 * sizeof(char));                    
                printf("TYPE ");
                scanf("%s", pt.e);
                fgets(pt.e, 20, stdin);
                len = strlen(pt.e);
                if((pt.e[len-1]) == '\n')
                  pt.e[len-1]='\0';
                for(k=0; k < strlen(pt.e)-1; k++) {
                if(!isalpha(pt.e[k])) break;
                }
                 if(k == strlen(pt.e)) break;
            }
            while(1);
    
    
            do {
                pt.f = malloc(40 * sizeof(char));                 
                printf("TYPE: ");
                scanf("%s", pt.f);
                fgets(pt.f, 40, stdin);
                len = strlen(pt.f);
                if((pt.f[len-1]) == '\n')
                  pt.f[len-1]='\0';
                for(k=0; k < strlen(pt.f)-1; k++) {
                if(!isalpha(pt.f[k])) break;
                }
                 if(k == strlen(pt.f)) break;
            }
            while(1);
    
    
            do {
                pt.g = malloc(20 * sizeof(char));                       
                printf("TYPE: ");
                scanf("%s", pt.g);
                fgets(pt.g, 20, stdin);
                len = strlen(pt.g);
                if((pt.g[len-1]) == '\n')
                  pt.g[len-1]='\0';
                for(k=0; k < strlen(pt.g)-1; k++) {
                if(!isalpha(pt.g[k])) break;
                }
                 if(k == strlen(pt.g)) break;
            }
            while(1);
        
        fprintf(filet, "\n%s - %s - %d - %.1lf - %s - %s - %s", pt.a, pt.b, pt.c, pt.d, pt.e, pt.f, pt.g);
    }
    The problem is with fprintf. And " [Linker error] undefined reference to `WinMain@16' " shows in compilator log.

    Thanks for your help.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    What is the problem with printf?

    And the problem with main is that you forgot to write it. Every program needs a main(); if you have it in another file, you'll have to combine them in a project (or similar) so that they get linked together.

  8. #8
    Registered User
    Join Date
    Dec 2013
    Posts
    23
    tabstop thank you for your response.

    1) The problem with fprintf is that the strings do not save in file.
    The function main is in another file and I have put there
    Code:
    #include "filet.txt"
    And it works. But problem still exists.

    2) Is everything ok with list?

    Thank you again!

    EDIT:// ok I solve the problem with main. But now
    Code:
    while (e->n != NULL) e = e->n;
    something is wrong with this line. Compilator says:
    Code:
     31 [Warning] assignment from incompatible pointer type
    Last edited by fkmk; 01-03-2014 at 10:30 AM.

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by fkmk View Post
    1) The problem with fprintf is that the strings do not save in file.
    Are you sure that's a problem with fprintf? You don't check if pt.a, pt.b, etc actually have valid data in them. Try printing them to the screen too, to verify.
    Quote Originally Posted by fkmk View Post
    The function main is in another file and I have put there
    Code:
    #include "filet.txt"
    And it works. But problem still exists.
    That's not how you work with multiple files. You should not include anything with code that will run*; you should only include header files, which contain definitions like function prototypes and type defs. Different files with runnable source code should each be in their own .c file (e.g. list.c, main.c). Then you compile each one into a separate object file (.o file) and link those together into your final executable. Exactly how to do that depends on your compiler and development environment (command line tools, IDE, etc).

    Quote Originally Posted by fkmk View Post
    2) Is everything ok with list?
    No.
    Code:
    LISTF p = NULL;
    LISTF e;
    while (e->n != NULL) e = e->n;
    e = (LISTF) malloc(sizeof(LISTF));
    e->n = NULL;
    if(!p) p=e;
    What are the contents of e after the declaration? Garbage. Uninitialized local variables have garbage contents, until you initialize them. That means that loop accesses random parts of memory, some of which you may not have access to. That means undefined behavior, which could cause your computer to crash.

    The loop is pointless anyway, since you overwrite e on the following line with a call to malloc. Also, don't cast malloc. And the best way to use malloc is to use the variable name in the sizeof. That asks malloc for "however much memory it takes to store the type of thing e points to". That way, if you change the definition of e, you still always allocate the right amount of memory. You should also check the return value of malloc -- it can fail.
    Code:
    e = malloc(sizeof(*e));

    The if (!p) check is also pointless. You explicitly initialize it to NULL, so !p will always be true, and the body of that if will always execute (i.e. p will always point to e).

    You never do anything with p or e after that, so your list contains nothing. It just creates a memory leak (calling malloc and never freeing it).

    Other problems/suggestions:

    • Programming is about problem solving, not writing code. Don't write 100+ lines of code before you test. Study the problem. Work it out with paper and pencil. Turn that solution into pseudo code. Turn that pseudo code into real code. Write about 5-10 lines of code at a time. Compile at maximum warning level and remove all warnings and errors. Then test and debug those 5-10 lines. Don't move on to the next 5-10 lines until you are 100% error free. This makes it very easy to find and fix problems: you only have to look at 5-10 lines at a time.
    • Global variables are evil. They should be used sparingly, and with caution. As a beginner, it's probably best not to use them at all. pt is a global and doesn't need to be. Declare it in the appropriate function and pass it to other functions if you need to share it.
    • Don't use magic numbers.
    • You should tell the user what they are supposed to enter. If you just say "type", they don't know if it's a number or word, or what that represents. Prompt them with a useful string, like "Please enter your first name: " or "Please enter the year of your car: ".
    • Why declare char pointers and use malloc? Especially when it appears you don't ever free the memory (which is a memory leak). You know the size you want ahead of time, so just declare them in the struct as arrays of the right size. See below.
    • Your code for getting pt.a, pt.b, pt.e, pt.f and pt.g are identical except for the size and the name of the variable you store it in. Whenever you find yourself repeating identical or nearly identical code, try putting that repeated code in a function. That way, you only have one bit of code that you have to maintain, debug and fix. See below.
    • Give your struct members useful names. What does a represent? b? Again, see below.


    Example
    Code:
    #define MAKE_LEN  20
    #define MODEL_LEN  40
    struct siala {    char make[MAKE_LEN];
        char model[MODEL_LEN];
        int year;
        double cost;
        ...
    }
    ...
    void get_text_input(const char *prompt, char *buf, int size)
    {
        do
            print prompt
            read up to size chars into buf (e.g. using fgets)
            process the input (e.g. strip the newline fgets leaves in the buffer)
        while not valid input
    }
    ...
    get_text_input("Please enter the make: ", pt.make, sizeof(pt.make));
    get_text_input("Please enter the model: ", pt.model, sizeof(pt.model));
    // similar for whatever pt.e, pt.f and pt.g represent
    See, isn't that much easier to understand and follow? If your code is hard to understand, it's easy to make mistakes, and hard to find or fix them.

    I can not stress enough how important it is to have a good, organized, methodical process for tackling programming problems.

    * There are exceptions, like in-line functions, that should be defined in a .h file and #included in other .c files, but that is rare.

  10. #10
    Registered User
    Join Date
    Dec 2013
    Posts
    23
    anduril462 thank you very much for your response.
    I will try to fix my code according to your tips.

    EDIT:// How to include structure to list? The list is empty and I do not know how to include there a structure. :/
    Last edited by fkmk; 01-03-2014 at 11:07 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 04-25-2013, 01:50 AM
  2. Replies: 1
    Last Post: 04-02-2009, 06:51 AM
  3. what does a linked list structure look like?
    By MalickT in forum C Programming
    Replies: 9
    Last Post: 05-26-2008, 05:19 PM
  4. Replies: 7
    Last Post: 03-26-2008, 03:21 AM
  5. Linked list w/ structure
    By 5rjK in forum C Programming
    Replies: 10
    Last Post: 12-12-2006, 06:18 AM