Thread: Seg faults. structs. pointers.

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    66

    Seg faults. structs. pointers.

    I'm having trouble with this program. it reads in a list of words from a text file and allows you to add words, search for words, compare 2 lists and print the list. the first line of the text file contains the language of the words, and the second line contains the number of words. the following lines contain the words. like so:

    Code:
    english
    14
    abjure
    abrogate
    abstemious
    acumen
    antebellum
    auspicious
    belie
    bellicose
    bowdlerize
    chicanery
    chromosome
    churlish
    circumlocution
    circumnavigate
    im getting a problem when i try to fscanf a value into the num_words variable in the structure. i get a seg fault error there.

    another problem im getting is where i let the for loop in open_file() run until MAX_WORDS... it gets crazy( line 76).
    i wrote the program to print the words read in so i can see that it was reading the file OK. when it runs till MAX_WORDS it prints all kinds of crazy characters and stuff. but if i change it to a->num_words it wont run. i know it has something to do with the pointers but i dont know how to fix it. ive spent like 3 hours trying to figure it out.

    also in that function there is the fscanf for a->lang and a->num_words. i have them commented out because i was trying to just increment a->num_words(line 78) this solved the first problem but didnt solve the following problem.

    and lastly, in the add_word() function when i add the words to a->b[num_words + 1] i get another seg fault.

    please let me know if you can help.

    here is the code
    Code:
    # include <stdio.h>
    # include <string.h>
    
    # define MAX_WORDS      20
    
    struct wordlist {
           char lang[15];
           int num_words;
           char b[MAX_WORDS][21];
    };
    
    void    open_file(struct wordlist *a);
    void    add_word(char word[21], struct wordlist *a);
    int     contains(char word[21], struct wordlist a);
    void    display_word_list(struct wordlist a);
    
    int main() {
        struct  wordlist a;
        char    word[21];
        int     c=0, sel, i=0;
                
        open_file(&a);       
    	
    		printf("Option 1\tAdd A Word\n");    
    		printf("Option 2\tContains\n");
    		printf("Option 3\tEqual Lists\n");
    		printf("Option 4\tDisplay List\n");
    		printf("Option 5\tExit\n");
    		scanf("%d", &sel);
    		
            if (sel ==1) {            
                printf("please enter a word to add: \n");
                scanf("%s", &word); 
                add_word(word, &a);
                printf("SUCCESS\n");
                for( i = 0; i <= MAX_WORDS; i++ ) {                        
                    printf("%s\n", a.b[i]);   
                }
            }
                    
            else if (sel ==2) {
                printf("Enter a word to search for: \n");
                scanf("%s", &word);
                c = contains(word, a);
                if( c == 1) 
                    printf("Word Found"); 
                else if ( c == 2) 
                    printf("Word Not Found"); 
            }
                            
            else if (sel ==3) {
                    
            }
            else if (sel ==4) {
                    
            }
            else if (sel ==5)
                return(0); 
            
            
        
    system("pause");
        return(0);
    }
    
    void open_file(struct wordlist *a){
        
        FILE    *ifp;
        int     i=0, j=0;
        
            ifp = fopen("input.txt", "r");
            //fscanf(ifp, "%s", a->lang);
            //fscanf(ifp, "%d", a->num_words);
            
            for( i = 0; i <= MAX_WORDS; i++ ) {                 
                fscanf(ifp, "%s", a->b[i]); 
    			a->num_words++;         
            }
            for( i = 0; i <= MAX_WORDS; i++ ) {                        
                    printf("%s\n", a->b[i]);   
            }
    	
    		fclose(ifp);
    }
    
    void add_word(char word[21], struct wordlist *a) {
    
        int     i=0, j;  
        
    		
            if ( a->num_words == MAX_WORDS ) {
                printf("List full, word not added.");
            }
            else {
                for ( i = 0; i < a->num_words; i++) {
                    if(strcmp(a->b[i], word)==0) {
                        break;
                    }
                    else {
                        printf("check");
                        strcpy(a->b[a->num_words+1], word);
                        //printf("check");
                    }
                }
            }
              
    }
    
    int contains(char word[21], struct wordlist a) {
        int    i=0;   
         
        for ( i = 0; i <= a.num_words; i++) {
            if (strcmp(a.b[i], word)==0) {
                return(1);
            }
            else {
                return(2);  
            }                
        }
    }
    
    
    /*
    void equal_lists() {
         
         
         
                  
    }
    
    void display_word_list(struct wordlist a) {
         int i=0;
         
             for (i=0; i<a.num_words;i++) {
                 printf("%s\n", a.b[i]);
             }
         
         
         
    }
    */
    i just realized that contains() doesent work either. but dont bother trying to figure it out unless it just jumps out at you.

    thanks a lot for the help.
    Last edited by ominub; 05-02-2009 at 09:52 PM.

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by ominub View Post
    i just realized that contains() doesent work either. but dont bother trying to figure it out unless it just jumps out at you.

    thanks a lot for the help.
    Right off the bat I can tell you that the else part is causing problems because the second return should be outside the loop.

  3. #3
    Registered User
    Join Date
    Feb 2009
    Posts
    66
    Quote Originally Posted by itCbitC View Post
    Right off the bat I can tell you that the else part is causing problems because the second return should be outside the loop.

    thanks, that was it. any idea about the rest?

  4. #4
    Registered User
    Join Date
    Feb 2009
    Posts
    66
    anyone?

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > for( i = 0; i <= MAX_WORDS; i++ )
    Well this ALWAYS steps off the end of your array, no matter what else happens.

    To index the array, it's
    for( i = 0; i < MAX_WORDS; i++ )

    Add to that, you should look at the return result of fscanf to determine whether any data was read.
    Or perhaps even use the second line (which I guess is the number of words)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Feb 2009
    Posts
    66
    ok great i changed that.

    i also printed the result of the 2 fscanf's and a->num_words gives me the location... 8978688... NOT the 14 it should read. how do i get it use the number it reads. i tried a.num_words and that didnt work.

    also, i want to use that number (14) for the array that uses MAX_WORDS because its scanning empty space its giving me a mess of extra stuff. when i put it in there now, the program prints out the two fcanfs for lang and num_words(num words prints 8978699) the loop must run that long because there is a long pause when i run it... then it crashes.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Post your latest code
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Feb 2009
    Posts
    66
    hasnt changed much but if i change what i need to it doesent compile

    Code:
    # include <stdio.h>
    # include <string.h>
    
    # define MAX_WORDS      20
    
    struct wordlist {
           char *lang[15];
           int  *num_words;
           char b[MAX_WORDS][21];
    };
    
    void    open_file(struct wordlist *a);
    void    add_word(char word[21], struct wordlist *a);
    int     contains(char word[21], struct wordlist a);
    void    display_word_list(struct wordlist a);
    
    int main() {
        struct  wordlist a;
        char    word[21];
        int     c=0, sel, i=0;
                
        open_file(&a);       
    	
    		printf("Option 1\tAdd A Word\n");    
    		printf("Option 2\tContains\n");
    		printf("Option 3\tEqual Lists\n");
    		printf("Option 4\tDisplay List\n");
    		printf("Option 5\tExit\n");
    		scanf("%d", &sel);
    		
            if (sel ==1) {            
                printf("please enter a word to add: \n");
                scanf("%s", &word); 
                add_word(word, &a);
                printf("SUCCESS\n\n");
                for( i = 0; i < MAX_WORDS; i++ ) {                        
                    printf("%s\n", a.b[i]);   
                }
            }
                    
            else if (sel ==2) {
                printf("Enter a word to search for: \n");
                scanf("%s", &word);
                c = contains(word, a);
                if( c == 1) 
                    printf("Word Found\n"); 
                else if ( c == 2) 
                    printf("Word Not Found\n"); 
            }
                            
            else if (sel ==3) {
                    
            }
            else if (sel ==4) {
                    
            }
            else if (sel ==5)
                return(0); 
            
            
        
    system("pause");
        return(0);
    }
    
    void open_file(struct wordlist *a){
        
        FILE    *ifp;
        int     i=0, j=0;
        
            ifp = fopen(".........txt", "r");
            fscanf(ifp, "%s", a->lang);
            printf("LANG %s\n", a->lang);
            fscanf(ifp, "%d", a->num_words);
            printf("NUMWORDS %d\n", a->num_words);
            
            for( i = 0; i < MAX_WORDS; i++ ) {                 
                fscanf(ifp, "%s", a->b[i]); 
    			//a->num_words++;         
            }
            for( i = 0; i < MAX_WORDS; i++ ) {                        
                    printf("%s\n", a->b[i]);   
            }
    	
    		fclose(ifp);
    }
    
    void add_word(char word[21], struct wordlist *a) {
    
        int     i=0, j;  
        
    		
            if ( (int)a->num_words == MAX_WORDS ) {
                printf("List full, word not added.");
            }
            else {
                for ( i = 0; i < a->num_words; i++) {
                    if(strcmp(a->b[i], word)==0) {
                        break;
                    }
                    else {                    
                        strcpy(a->b[ 14   ], word);                    
                    }
                }
            }
              
    }
    
    int contains(char word[21], struct wordlist a) {
        int    i=0;   
         
        for ( i = 0; i <= a.num_words; i++) {
            if (strcmp(a.b[i], word)==0) 
                return(1);               
        }
        return(2);
    }

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > fscanf(ifp, "%d", &a->num_words);
    > printf("NUMWORDS %d\n", a->num_words);

    If you're using gcc (or an IDE like code::blocks which uses gcc as it's compiler), then add the
    -Wall
    compiler option.
    It will tell you a lot of useful stuff.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Feb 2009
    Posts
    66
    dammit! i looked at that line for hours and it never crossed my mind to do that. thank you!!!

    wait what is gcc? im using bloodshed's dev-c++ compiler.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Yeah, that's another IDE which also uses gcc under the hood.

    Something like project->settings->compiler->options should get you close to where you can add your own flags.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Just my 2c, but add_word() should be written more like
    Code:
    void add_word(char word[21], struct wordlist *a)
    {
            int i=0;
    
            if ( a->num_words == MAX_WORDS ) {
                printf("List full, word not added.");
                return;
            }
            else {
                for (i = 0; i < a->num_words; i++)
                    if (strcmp(a->b[i], word) == 0)
                        return;
            }
            strcpy(a->b[i], word); /* called only if the word to be added is un-matched */
            a->num_words++;
    }

  13. #13
    Registered User
    Join Date
    Feb 2009
    Posts
    66
    Quote Originally Posted by itCbitC View Post
    Just my 2c, but add_word() should be written more like
    Code:
    void add_word(char word[21], struct wordlist *a)
    {
            int i=0;
    
            if ( a->num_words == MAX_WORDS ) {
                printf("List full, word not added.");
                return;
            }
            else {
                for (i = 0; i < a->num_words; i++)
                    if (strcmp(a->b[i], word) == 0)
                        return;
            }
            strcpy(a->b[i], word); /* called only if the word to be added is un-matched */
            a->num_words++;
    }

    thank you.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-25-2009, 09:29 PM
  2. Confused with pointers and structs
    By jalex39 in forum C Programming
    Replies: 6
    Last Post: 10-12-2008, 02:22 PM
  3. It seg faults right away
    By Brimak86 in forum C Programming
    Replies: 6
    Last Post: 01-31-2008, 10:40 PM
  4. Seg Faults at Random
    By mrpickle in forum C Programming
    Replies: 5
    Last Post: 01-15-2004, 03:42 PM
  5. pointers and structs
    By alexir in forum C Programming
    Replies: 0
    Last Post: 10-20-2001, 01:28 AM