Help with C Programming Please!

Discussion in 'OT Technology' started by wytefyre, Apr 9, 2007.

  1. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    I'm getting a segmentation error, but I'm not sure how to fix it. Basically, this program is supposed to read from the command line the file that it's supposed to edit (ex: a.out planet.m) and then do work on the file itself. My problem is how I'm trying to get the filename from the command line, I believe. This is the segment of code I'm using:

    Code:
    int main(char *argv[]) {
      int file_check;
      float kg_mass;
      char temp[11], filename[MAX_SIZE_FN];
    
    [I]  temp=argv[1];[/I]
      file_check=getFilename(temp,filename);
    
    ...
    
    The specific error I'm getting there is (line 22 is the italicized line):

    hw1.c: In function ‘main’:
    hw1.c:22: error: incompatible types in assignment

    Thank you for any and all help!

    Edit: Looking back over this post, I realized I was being a little incorrect. The segmentation error I was getting was without using that temp variable and directly passing the argv command through.
     
    Last edited: Apr 9, 2007
  2. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    Hm... Check that... I'm now getting a segmentation error when I try to do that...

    I'm not sure if it'll help or not, but here's my entire program. It's supposed to read from a small data file with data in scientific notation and print it out after converting it into scientific notation, and the second part is the simple data file I'm using (planet.m):

    Code:
    #include <stdio.h>
    #include <string.h>
    
    #define MAX_SIZE_FN 11
    #define KGtoLBS 2.2046226218488
    
    int getFilename( char args[], char file[] );
    int readFile( char file[] );
    float convertKgToLbs( float kg );
    
    int main(char *argv[]) {
      int file_check;
      float kg_mass;
      char temp[11], filename[MAX_SIZE_FN];
    
      strcpy(temp,*argv);
      file_check=getFilename(temp,filename);
    
      if(file_check != 0)
        printf("Error: insufficient space for filename. Please enter a shorter name. \n");
      else {
        file_check=readFile(filename);
        if(file_check != 0)
          printf("Error: file could not be read. Please check your files.\n");
      }
    
      return 0;
    }
    
    int getFilename(char args[], char file[]) {
      if(strlen(args)>MAX_SIZE_FN)
        return 1;
      else {
        file = args;
        return 0;
      }
    }
    
    int readFile(char file[]) {
      char file_line[100],temp_dump[20],temp_calc[30];
      float calc,conv;
      FILE *input_file, *output_file;
    
      input_file = fopen(file,"r");
    
      if(fgets(file_line,100,input_file)==NULL)
        return 1;
      else {
        fgets(file_line,100,input_file);
        strcat(file_line,"\tLBS");
        printf("%s",file_line);
    
        while(fgets(file_line,100,input_file) != NULL) {
          sscanf(file_line,"%s%s",&temp_dump,&temp_calc);
          calc = atof(temp_calc);
          conv=convertKgToLbs(calc);
          printf("%s\t%e",temp_dump,conv);
        }
       }
      fclose(input_file);
      return 0;
    }
    
    float convertKgToLbs(float kg) {
      kg = kg*KGtoLBS;
      return kg;
    }
    
    Code:
    Planet  Mass(kg)
    Mercury 3.303000e+23
    Venus   4.869000e+24
    Earth   5.976000e+24
    Mars    6.421000e+23
    Jupiter 1.900000e+27
    Saturn  5.688000e+26
    Uranus  8.686000e+25
    Neptune 1.024000e+26
    Pluto   1.290000e+22
    
    Thanks again for the help!
     
    Last edited: Apr 9, 2007
  3. Penguin Man

    Penguin Man Protect Your Digital Liberties

    Joined:
    Apr 27, 2002
    Messages:
    21,696
    Likes Received:
    0
    Location:
    Edmonton, AB
    main needs to be main(int argc, char **argv).

    What's happening is that if main only takes one argument, that argument becomes the number of arguments (which is what argc would usually be). Try this:

    Code:
    #include <stdio.h>
    
    int main(char **argv) {
        printf("%d\n", argv);
    
        return(0);
    }
    argv is just a pointer to a pointer, which can be treated as an integer, so the program compiles and runs with no problems. Notice that it prints out how many command-line arguments you pass it each time (where we include the program name as an argument).

    Since argv is set to the number of arguments, when you dereference with argv[1] it tries to get the value stored at the memory address argv + 1, which is probably in kernel space (unless you're passing billions of arguments to your program ;)).
     
  4. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    Awesome, thanks! I think I've got it all figured out now.

    Thank you again!
     
  5. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    So instead of making another new thread for asking for help, I thought I'd stick with the one thread.

    So this time, I'm having trouble with structs in this program that I have to write that is a mini-sudoku puzzle thing. Specifically, I'm getting an error that reads:

    "puzzler.c:101: warning: passing argument 1 of ‘atoi’ makes pointer from integer without a cast"

    I seem to get these a lot. This one occurs in the function getPuzzle with the line starting with "puzzles.answer". I went ahead and attached all the code needed, plus a sample file that gets passed via command-line arguments. The code overall isn't done, I'm just working on getting parts up and running as I go. Also, the basic structure of the code cannot be changed, only added to.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <time.h>
    
    #define MAX_LINE 20
    #define SIZE 9
    
    struct Puzzle
    {
       int answer[SIZE][SIZE];
       int sofar[SIZE][SIZE];
    } puzzles;
    
    void printTable( int tbl[SIZE][SIZE] );
    void prompt( );
    void getPuzzle(  char filename[ ]);
    void checkAnswer( );
    
    int main( int argc, char *argv[ ] )
    {
      int done = 0;
      char cmd = 'a',file[20];
      char line[MAX_LINE];
      strcpy(file,argv[1]);
      getPuzzle( file );
      do
      {
          printTable( puzzles.sofar );
          prompt( );
          fgets( line, sizeof(line), stdin );
          sscanf( line, "%c", &cmd  );
          switch( cmd )
          {
              case 'p':
              
    
                    break;
              case 'e':
                    printf( "What row column entry?  (rows and columns start at index 0)\n" );
    
    
    
                    break;
              case 'c':
                    printf( "Checking answer?\n" );
                    checkAnswer( );
                    break;
              case 'g':
                    printf( "Giving up so soon?\n" );
    
              case 'q':
                    done = 1;
          }
      
      } while( !done );
      return 0;
    }
    
    void prompt( )
    {
            printf( "\nWhat would you like to do: quit (q),  print table (p)");
            printf( "   enter an entry (e)  check answer (c)  or give up (g)?\n > " );
    }
    
    void printTable( int puzz[SIZE][SIZE] )
    {
            printf( "-------------------------------------------------------\n" );
            for(int i=0;i<SIZE;i++)
              for(int j=0;j<SIZE;j++) {
                if(puzz[i][j] != 0)
                  printf("| %d ",puzz[i][j]);
                else if(puzz[i][j] == 0)
                  printf("|   ");
                
                if(j == 8)
                  printf("|\n");
              }
    }
    
    void getPuzzle( char filename[ ] )
    {
      int i,j;
      char line[SIZE];
      FILE *in;
      in = fopen( filename, "r" );
      if ( in == NULL )
      { 
         printf( "Error reading File" );
         return;
      }
    
      for(i=0;i<SIZE;i++) {
        fgets(line,SIZE,in);
        for(j=0;j<SIZE;j++)
          puzzles.answer[i][j]=(int) atoi((char) line[j]);
      }
    
      fclose(in);
            // randomly select which values to display
      int random;
      for ( int i=0; i<SIZE; i++ )
         for ( int j=0; j<SIZE; j++ )
         {
            random = (int) rand( ) % 2;     // 2 easy = 50% chance of showing num
            if ( random == 1 )
                    puzzles.sofar[i][j] = puzzles.answer[i][j];
         }
    
    }
    
    void checkAnswer( )
    {
       int isCorrect = 1;
    
       if ( isCorrect )
            printf( "\nYou are correct!\n" );
       else
            printf( "\nNot Right!\n" );
    
    }
    
    puzzle:
    Code:
    1 2 3 4 5 6 7 8 9
    2 3 4 5 6 7 8 9 1
    3 4 5 6 7 8 9 1 2
    4 5 6 7 8 9 1 2 3
    5 6 7 8 9 1 2 3 4
    6 7 8 9 1 2 3 4 5
    7 8 9 1 2 3 4 5 6
    8 9 1 2 3 4 5 6 7
    9 1 2 3 4 5 6 7 8
    
    Thank you very much for any and all help!
     
  6. skinjob

    skinjob Active Member

    Joined:
    Jan 6, 2001
    Messages:
    2,337
    Likes Received:
    0
    Location:
    Aztlán


    atoi expects a pointer to a NULL terminated string. You're getting that warning because you're passing it a char.

    I see what you're trying to do, and atoi isn't the right approach if you're parsing each line character-by-character to fetch the digits. You can simply take the ascii value of the digit and subtract the ascii value of '0' to get the numerical value of the digit.

    puzzles.answer[j] = line[j] - '0';
     
  7. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    Hm... I need to study ASCII more, I guess. Thanks! Let's see how long it is until I get stuck again.

    Thank you!
     
  8. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    Ok, I'm stumped. I can't see why I can't properly input from the file now... Here's an updated version of my code - the problem has to be in getPuzzle...

    Thank you so much for the help! I really appreciate it!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <time.h>
    
    #define MAX_LINE 20
    #define SIZE 9
    
    struct Puzzle
    {
       int answer[SIZE][SIZE];
       int sofar[SIZE][SIZE];
    } puzzles;
    
    void printTable( int tbl[SIZE][SIZE] );
    void prompt( );
    void getPuzzle(  char filename[ ]);
    void checkAnswer( );
    
    int main( int argc, char *argv[ ] )
    {
      int done = 0,row,column,num;
      char cmd = 'a',dump;
      char line[MAX_LINE];
      getPuzzle( argv[1] );
      do
      {
          printTable( puzzles.sofar );
          prompt( );
          fgets( line, sizeof(line), stdin );
          sscanf( line, "%c", &cmd  );
          switch( cmd )
          {
              case 'p':
                    break;
              case 'e':
                    printf( "What row column entry?  (rows and columns start at index 0)\n" );
                    scanf("%d%c%d%c%d%c",&row,&dump,&column,&dump,&num,&dump);
                    puzzles.sofar[row][column]=num;
                    break;
              case 'c':
                    printf( "Checking answer?\n" );
                    checkAnswer( );
                    break;
              case 'g':
                    printf( "Giving up so soon?\n" );
    
              case 'q':
                    done = 1;
          }
      
      } while( !done );
      return 0;
    }
    
    void prompt( )
    {
            printf( "\nWhat would you like to do: quit (q),  print table (p)");
            printf( "   enter an entry (e)  check answer (c)  or give up (g)?\n > " );
    }
    
    void printTable( int puzz[SIZE][SIZE] )
    {
            printf( "-------------------------------------\n" );
            for(int i=0;i<SIZE;i++) {
              for(int j=0;j<SIZE;j++) {
                if(puzz[i][j] >= 1 && puzz[i][j] <= 9)
                  printf("| %d ",puzz[i][j]);
                else
                  printf("|   ");
                
                if(j == 8)
                  printf("|\n");
              }
              printf( "-------------------------------------\n" );
            }
    }
    
    void getPuzzle( char filename[ ] )
    {
      int i,j;
      char line[SIZE*2-1];
      FILE *in;
      in = fopen( filename, "r" );
      if ( in == NULL )
      { 
         printf( "Error reading File" );
         return;
      }
    
      for(i=0;i<SIZE;i++) {
        fgets(line,SIZE*2-1,in);
        for(j=0;j<SIZE*2-1;j++) {
          printf("%c",line[j]);
          if(j%2==0 || j==0)
            puzzles.answer[i][j]=(int) ( line[j]-'0' );
        }
      }
    
      fclose(in);
            // randomly select which values to display
      int random;
      for ( int i=0; i<SIZE; i++ )
         for ( int j=0; j<SIZE; j++ )
         {
            random = (int) rand( ) % 2;     // 2 easy = 50% chance of showing num
            if ( random == 1 )
                    puzzles.sofar[i][j] = puzzles.answer[i][j];
         }
    
    }
    
    void checkAnswer( )
    {
       int isCorrect = 1;
    
       for(int i=0;i<SIZE;i++)
         for(int j=0;j<SIZE;j++)
           if(puzzles.sofar[i][j]!=puzzles.answer[i][j]) {
             isCorrect = 0;
             break;
           }
    
       if ( isCorrect )
            printf( "\nYou are correct!\n" );
       else
            printf( "\nNot Right!\n" );
    
    }
    
     
  9. skinjob

    skinjob Active Member

    Joined:
    Jan 6, 2001
    Messages:
    2,337
    Likes Received:
    0
    Location:
    Aztlán
    You're assuming your input will always consist of SIZE*2-1 lines, where each line contains SIZE*2-1 characters, which isn't the case based on the sample input you provided earlier.
     
  10. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    Hm... I think I see where you're going with this, but it didn't help. For some reason, it would only read the first 5 lines of the puzzle and then stop. I changed the outer loop to run for twice SIZE (18) and then it finished with only reading one more line... Weird...

    Well, it's reading the string in properly, now, and all that's left is to make sure that it's actually putting the correct numbers into the struct. Thanks again!

    Edit: Check that - I'm still only getting 5 lines of it, and it's putting an entire blank line between each line of numbers. What the crap!?
     
    Last edited: Apr 16, 2007
  11. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    Yarg!

    So, I have yet another programming problem. This time, I think it's only in one area, as the rest of my program appears to be in working order.

    I need to read in a string from a textfile from a command-line argument, and then count how many times a certain word appears, then sort by word, grammar type, and number of occurances.

    I got it all to work, except how to properly read in the string and get the individual words. It's the very last function in my program, and I'm sure I'm doing it wrong. How does one get individual words from a sentence passed as a string?

    For reference, or mocking, I attached a copy of my code and a test file. Thanks for any and all help, yet again! You guys rock!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    # define MAX_WORD_SIZE 15
    # define NUMRECORDS 23
    # define TRUE 1
    # define FALSE 0
    
    enum columns { WORD, GRAMMAR, QUANTITY };
    
    typedef struct 
    {
       char word[MAX_WORD_SIZE];
       enum { noun, verb, adverb, article, pronoun, adjective } type;
       int numTimesAppear;
    } record;
    
    record temp_swap={"the",article,0};
    
    record wordlist[NUMRECORDS] = 
            {
                      { "the", article, 0 }
                    , { "their", pronoun, 0 }
                    , { "a", article, 0 }
                    , { "difficult", adjective, 0 }
                    , { "run", verb, 0 }
                    , { "you", pronoun, 0 }
                    , { "game", noun, 0 }
                    , { "quickly", adverb, 0 }
                    , { "name", noun, 0 }
                    , { "he", pronoun, 0 }
                    , { "team", noun, 0 }
                    , { "quietly", adverb, 0 }
                    , { "president", noun, 0 }
                    , { "it", pronoun, 0 }
                    , { "interest", noun, 0 }
                    , { "promptly", adverb, 0 }
                    , { "whom", pronoun, 0 }
                    , { "ball", noun, 0 }
                    , { "decide", verb, 0 }
                    , { "she", pronoun, 0 }
                    , { "land", noun, 0 }
                    , { "is", verb, 0 }
                    , { "of", article, 0 }
            };
    
    int processFile( char fn[ ] );
    void printRecords( );
    void sortRecords( enum columns which );
    
    int main( int argc, char *argv[ ]  )
    { 
       if (  argc != 2 )
       { 
            printf( "Usage: %s filename\n", argv[0] );
            return -1;
       }
       if (  processFile( argv[1] ) < 0 )
       { 
            printf( "Error on file: %s \n", argv[1] );
            return -1;
       }
    
       printRecords( );
       sortRecords( WORD );
       printf( "\n====================================\n" );
       printf( "\n========Sorted by word==============\n" );
       printf( "\n====================================\n" );
       printRecords( );
    
       sortRecords( GRAMMAR );
       printf( "\n====================================\n" );
       printf( "\n========Sorted by type==============\n" );
       printf( "\n====================================\n" );
       printRecords( );
    
       sortRecords( QUANTITY );
       printf( "\n====================================\n" );
       printf( "\n=======Sorted by quantity===========\n" );
       printf( "\n====================================\n" );
       printRecords( );
    }
    void printRecords( )
    {
       printf( "\n           WORD\t      TYPE\t# APPEAR\n" );
    
       char grammar[6][10]={"noun","verb","adverb","article","pronoun","adjective"};
    
       for( int i=0; i<NUMRECORDS; i++ )
       {
    
         // Switch Statement
            if(wordlist[i].type == 0)
              printf( "%15s\t%10s\t%3d\n", wordlist[i].word,grammar[0], wordlist[i].numTimesAppear );
            else if(wordlist[i].type == 1)
              printf( "%15s\t%10s\t%3d\n", wordlist[i].word,grammar[1], wordlist[i].numTimesAppear );
            else if(wordlist[i].type == 2)
              printf( "%15s\t%10s\t%3d\n", wordlist[i].word,grammar[2], wordlist[i].numTimesAppear );
            else if(wordlist[i].type == 3)
              printf( "%15s\t%10s\t%3d\n", wordlist[i].word,grammar[3], wordlist[i].numTimesAppear );
            else if(wordlist[i].type == 4)
              printf( "%15s\t%10s\t%3d\n", wordlist[i].word,grammar[4], wordlist[i].numTimesAppear );
            else if(wordlist[i].type == 5)
              printf( "%15s\t%10s\t%3d\n", wordlist[i].word,grammar[5], wordlist[i].numTimesAppear );
       }
    }
    void sortRecords( enum columns which )
    {
      int i,j;
    
      if(which == WORD) {
        for(i=0;i<NUMRECORDS;i++)
          for(j=0;j<NUMRECORDS;j++)
            if( wordlist[j+1].word < wordlist[j].word) {
              strcpy(temp_swap.word,wordlist[j+1].word);
              strcpy(wordlist[j+1].word,wordlist[j].word);
              strcpy(wordlist[j].word,temp_swap.word);
    
              temp_swap.type=wordlist[j+1].type;
              wordlist[j+1].type = wordlist[j].type;
              wordlist[j].type=temp_swap.type;
    
              temp_swap.numTimesAppear=wordlist[j+1].numTimesAppear;
              wordlist[j+1].numTimesAppear = wordlist[j].numTimesAppear;
              wordlist[j].numTimesAppear=temp_swap.numTimesAppear;
            }
      }
      if(which == GRAMMAR) {
        for(i=0;i<NUMRECORDS;i++)
          for(j=0;j<NUMRECORDS;j++)
            if(wordlist[j+1].type > wordlist[j].type) {
              strcpy(temp_swap.word,wordlist[j+1].word);
              strcpy(wordlist[j+1].word,wordlist[j].word);
              strcpy(wordlist[j].word,temp_swap.word);
    
              temp_swap.type=wordlist[j+1].type;
              wordlist[j+1].type = wordlist[j].type;
              wordlist[j].type=temp_swap.type;
    
              temp_swap.numTimesAppear=wordlist[j+1].numTimesAppear;
              wordlist[j+1].numTimesAppear = wordlist[j].numTimesAppear;
              wordlist[j].numTimesAppear=temp_swap.numTimesAppear;
            }
      }
      if(which == QUANTITY) {
        for(i=0;i<NUMRECORDS;i++)
          for(j=0;j<NUMRECORDS;j++)
            if(wordlist[j+1].numTimesAppear < wordlist[j].numTimesAppear) {
              strcpy(temp_swap.word,wordlist[j+1].word);
              strcpy(wordlist[j+1].word,wordlist[j].word);
              strcpy(wordlist[j].word,temp_swap.word);
    
              temp_swap.type=wordlist[j+1].type;
              wordlist[j+1].type = wordlist[j].type;
              wordlist[j].type=temp_swap.type;
    
              temp_swap.numTimesAppear=wordlist[j+1].numTimesAppear;
              wordlist[j+1].numTimesAppear = wordlist[j].numTimesAppear;
              wordlist[j].numTimesAppear=temp_swap.numTimesAppear;
            }
      }
    }
    
    int processFile( char fn[ ] )
    {
       FILE *file;
       char line[81],word[MAX_WORD_SIZE];
       int i;
    
       if ( (file = fopen( fn, "r" )) == NULL )
       {
            return -2;
       }
    
       while( fgets(line, sizeof(line), file ) != NULL )
       {
         sscanf(line,"%c ",word);
         while(word[strlen(word)] != '\0') {
    
           for(i=0;i<NUMRECORDS;i++)  {
             if(word == wordlist[i].word) {
               wordlist[i].numTimesAppear += 1;
               break;
             }
           }
           
           sscanf(line,"%c ",word);
         }
       }
       fclose(file);
       return 0;
    }
    
    testfile:
    Code:
    the that their is a difficult run for
    you and name game quickly he team
    quietly it -whom- president interest promptly
    decide she. Land! OF prey BALL balls?
    
     
  12. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    Well, I messed with my program some, talked to the TA about it, and I still can't get it to work. Now I'm getting the following error:

    *** stack smashing detected ***: ./a.out terminated
    Aborted (core dumped)

    Anyone know how to fix this? Here's a copy of my updated code. Thanks for the help!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    # define MAX_WORD_SIZE 15
    # define NUMRECORDS 23
    # define TRUE 1
    # define FALSE 0
    
    enum columns { WORD, GRAMMAR, QUANTITY };
    
    typedef struct 
    {
       char word[MAX_WORD_SIZE];
       enum { noun, verb, adverb, article, pronoun, adjective } type;
       int numTimesAppear;
    } record;
    
    record temp_swap={"the",article,0};
    
    record wordlist[NUMRECORDS] = 
            {
                      { "the", article, 0 }
                    , { "their", pronoun, 0 }
                    , { "a", article, 0 }
                    , { "difficult", adjective, 0 }
                    , { "run", verb, 0 }
                    , { "you", pronoun, 0 }
                    , { "game", noun, 0 }
                    , { "quickly", adverb, 0 }
                    , { "name", noun, 0 }
                    , { "he", pronoun, 0 }
                    , { "team", noun, 0 }
                    , { "quietly", adverb, 0 }
                    , { "president", noun, 0 }
                    , { "it", pronoun, 0 }
                    , { "interest", noun, 0 }
                    , { "promptly", adverb, 0 }
                    , { "whom", pronoun, 0 }
                    , { "ball", noun, 0 }
                    , { "decide", verb, 0 }
                    , { "she", pronoun, 0 }
                    , { "land", noun, 0 }
                    , { "is", verb, 0 }
                    , { "of", article, 0 }
            };
    
    int processFile( char fn[ ] );
    void printRecords( );
    void sortRecords( enum columns which );
    
    int main( int argc, char *argv[ ]  )
    { 
       if (  argc != 2 )
       { 
            printf( "Usage: %s filename\n", argv[0] );
            return -1;
       }
       if (  processFile( argv[1] ) < 0 )
       { 
            printf( "Error on file: %s \n", argv[1] );
            return -1;
       }
    
       printRecords( );
       sortRecords( WORD );
       printf( "\n====================================\n" );
       printf( "\n========Sorted by word==============\n" );
       printf( "\n====================================\n" );
       printRecords( );
    
       sortRecords( GRAMMAR );
       printf( "\n====================================\n" );
       printf( "\n========Sorted by type==============\n" );
       printf( "\n====================================\n" );
       printRecords( );
    
       sortRecords( QUANTITY );
       printf( "\n====================================\n" );
       printf( "\n=======Sorted by quantity===========\n" );
       printf( "\n====================================\n" );
       printRecords( );
    }
    void printRecords( )
    {
       printf( "\n           WORD\t      TYPE\t# APPEAR\n" );
    
       char grammar[6][10]={"noun","verb","adverb","article","pronoun","adjective"};
    
       for( int i=0; i<NUMRECORDS; i++ )
       {
    
         // Switch Statement
         switch (wordlist[i].type) {
         case 0:
              printf( "%15s\t%10s\t%3d\n", wordlist[i].word,grammar[0], wordlist[i].numTimesAppear );
              break;
         case 1:
              printf( "%15s\t%10s\t%3d\n", wordlist[i].word,grammar[1], wordlist[i].numTimesAppear );
              break;
         case 2:
              printf( "%15s\t%10s\t%3d\n", wordlist[i].word,grammar[2], wordlist[i].numTimesAppear );
              break;
         case 3:
              printf( "%15s\t%10s\t%3d\n", wordlist[i].word,grammar[3], wordlist[i].numTimesAppear );
              break;
         case 4:
              printf( "%15s\t%10s\t%3d\n", wordlist[i].word,grammar[4], wordlist[i].numTimesAppear );
              break;
         case 5:
              printf( "%15s\t%10s\t%3d\n", wordlist[i].word,grammar[5], wordlist[i].numTimesAppear );
              break;
         }
       }
    }
    
    void sortRecords( enum columns which )
    {
      int i,j;
    
      if(which == WORD) {
        for(i=0;i<NUMRECORDS;i++)
          for(j=0;j<NUMRECORDS;j++)
            if( strcmp(wordlist[j].word,wordlist[j+1].word) >= 0) {
              strcpy(temp_swap.word,wordlist[j+1].word);
              strcpy(wordlist[j+1].word,wordlist[j].word);
              strcpy(wordlist[j].word,temp_swap.word);
    
              temp_swap.type=wordlist[j+1].type;
              wordlist[j+1].type = wordlist[j].type;
              wordlist[j].type=temp_swap.type;
    
              temp_swap.numTimesAppear=wordlist[j+1].numTimesAppear;
              wordlist[j+1].numTimesAppear = wordlist[j].numTimesAppear;
              wordlist[j].numTimesAppear=temp_swap.numTimesAppear;
            }
      }
      if(which == GRAMMAR) {
        for(i=0;i<NUMRECORDS;i++)
          for(j=0;j<NUMRECORDS;j++)
            if(wordlist[j+1].type > wordlist[j].type) {
              strcpy(temp_swap.word,wordlist[j+1].word);
              strcpy(wordlist[j+1].word,wordlist[j].word);
              strcpy(wordlist[j].word,temp_swap.word);
    
              temp_swap.type=wordlist[j+1].type;
              wordlist[j+1].type = wordlist[j].type;
              wordlist[j].type=temp_swap.type;
    
              temp_swap.numTimesAppear=wordlist[j+1].numTimesAppear;
              wordlist[j+1].numTimesAppear = wordlist[j].numTimesAppear;
              wordlist[j].numTimesAppear=temp_swap.numTimesAppear;
            }
      }
      if(which == QUANTITY) {
        for(i=0;i<NUMRECORDS;i++)
          for(j=0;j<NUMRECORDS;j++)
            if(wordlist[j+1].numTimesAppear < wordlist[j].numTimesAppear) {
              strcpy(temp_swap.word,wordlist[j+1].word);
              strcpy(wordlist[j+1].word,wordlist[j].word);
              strcpy(wordlist[j].word,temp_swap.word);
    
              temp_swap.type=wordlist[j+1].type;
              wordlist[j+1].type = wordlist[j].type;
              wordlist[j].type=temp_swap.type;
    
              temp_swap.numTimesAppear=wordlist[j+1].numTimesAppear;
              wordlist[j+1].numTimesAppear = wordlist[j].numTimesAppear;
              wordlist[j].numTimesAppear=temp_swap.numTimesAppear;
            }
      }
    }
    
    int processFile( char fn[ ] )
    {
       FILE *file;
       char line[81],word[MAX_WORD_SIZE];
       int i,val=0;
    
       if ( (file = fopen( fn, "r" )) == NULL )
       {
            return -2;
       }
    
       while( fgets(line, sizeof(line), file ) != NULL )
       {
         char curr = line[val];
         while(curr != '\0') {
           if(isspace(curr) != 0) {
             word[val] = tolower(curr);
             word[val+1] = '\0';
           }
           else if(isspace(curr) == 0) {
             for(i=0;i<NUMRECORDS;i++) {
               if(strcmp(word,wordlist[i].word) == 0)
                 wordlist[i].numTimesAppear += 1;
             }
           }
           val++;
           curr = line[val];
         }
         val = 0;
       }
       fclose(file);
       return 0;
    }
    
     
  13. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    I tried it, and I couldn't place it. Granted, I'm not 100% proficient in using debuggers, and we only had a short tutorial in this class I'm taking. This is what gdb gives me:

    Edit: I know for a fact that it keeps crashing in my last function - processFile, though. It's something about how I'm dealing with the string that's read from the file.

    Starting program: /home/josh/CS157/HW3/a.out testfile
    *** stack smashing detected ***: /home/josh/CS157/HW3/a.out terminated

    Program received signal SIGABRT, Aborted.
    0xffffe410 in __kernel_vsyscall ()
    (gdb) bt
    #0 0xffffe410 in __kernel_vsyscall ()
    #1 0xb7e81df0 in raise () from /lib/tls/i686/cmov/libc.so.6
    #2 0xb7e83641 in abort () from /lib/tls/i686/cmov/libc.so.6
    #3 0xb7eb79bb in ?? () from /lib/tls/i686/cmov/libc.so.6
    #4 0x000000f0 in ?? ()
    #5 0x00000006 in ?? ()
    #6 0x00000004 in ?? ()
    #7 0xb7f7f8d8 in ?? () from /lib/tls/i686/cmov/libc.so.6
    #8 0x00000021 in ?? ()
    #9 0xbfd669e5 in ?? ()
    #10 0x0000001a in ?? ()
    #11 0xb7f7f8fb in ?? () from /lib/tls/i686/cmov/libc.so.6
    #12 0x0000000c in ?? ()
    #13 0x00000004 in ?? ()
    #14 0x00000004 in ?? ()
    #15 0x00000007 in ?? ()
    #16 0xbfd66e7c in ?? ()
    #17 0xbfd65e6c in ?? ()
    #18 0xbfd65748 in ?? ()
    #19 0xb7f7f8fb in ?? () from /lib/tls/i686/cmov/libc.so.6
    #20 0x0000000c in ?? ()
    #21 0xbfd65740 in ?? ()
    #22 0x00000025 in ?? ()
    ---Type <return> to continue, or q <return> to quit---
    #23 0x494ce550 in ?? ()
    #24 0xb7f7b62b in ?? () from /lib/tls/i686/cmov/libc.so.6
    #25 0x00000010 in ?? ()
    #26 0xb7f94ff4 in ?? () from /lib/tls/i686/cmov/libc.so.6
    #27 0xbfd669e5 in ?? ()
    #28 0x0000001a in ?? ()
    #29 0xbfd65750 in ?? ()
    #30 0x00000006 in ?? ()
    #31 0xb7f7f8d8 in ?? () from /lib/tls/i686/cmov/libc.so.6
    #32 0x00000021 in ?? ()
    #33 0x00000000 in ?? ()
    (gdb)
     
    Last edited: Apr 24, 2007
  14. skinjob

    skinjob Active Member

    Joined:
    Jan 6, 2001
    Messages:
    2,337
    Likes Received:
    0
    Location:
    Aztlán
    try initializing the word buffer to an empty string.
    word[0] = 0;
     
  15. Penguin Man

    Penguin Man Protect Your Digital Liberties

    Joined:
    Apr 27, 2002
    Messages:
    21,696
    Likes Received:
    0
    Location:
    Edmonton, AB
    Alternately memset(word, 0, MAX_WORD_SIZE);.

    I'm partial to memset because then if you do something with the beginning of the string, you know that the end is still full of nulls.
     
  16. samm

    samm Next in Line

    Joined:
    Dec 22, 2000
    Messages:
    2,630
    Likes Received:
    0
    Location:
    San Jose, CA
    compile with debug symbols if you aren't already doing so: gcc -g foo.c

    if you are: your stack trace is clearly bogus, set breakpoints and figure out where your code walks off into the weeds
     
  17. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    I tried setting the word variable as "temp" and I'm still getting a stack dump.

    I know where the problem is - it's in that last function processFile in the while loop where I read data from the file. Something about how I'm handling that data isn't right. I commented that section out and it works fine.

    Any ideas on what I'm doing wrong for that part?
     
  18. Bruticus

    Bruticus half dead OT Supporter

    Joined:
    Apr 10, 2004
    Messages:
    4,608
    Likes Received:
    0
    Location:
    Melbourne
    I spent a couple of minutes playing around with the processFile function. Attached is a better one, but it is by no means perfect.

    A couple of things of note, when testing it I noticed there is something wrong with your sortRecords function as there is a null word in the last 3 sorts.

    You'll definately need to debug it more, but it's a start that will actually compile.

    Code:
    {
       FILE *file;
       char line[81],word[MAX_WORD_SIZE];
       int i,val, j;
       char curr;
    
       if ( (file = fopen( fn, "r" )) == NULL )
       {
            return -2;
       }
    
       while( fgets(line, sizeof(line), file ) != NULL )
       {
            val = 0;
            i = 0;
            curr = line[val];
    
            while( curr != '\0' ){
                    if( curr == '\n' ){
                            word[i] = '\0';
    
                            for( j = 0 ; j < NUMRECORDS ; j++ ){
                                    if( strcmp(word, wordlist[j].word) == 0 ){
                                            wordlist[j].numTimesAppear += 1;
                                    }
                            }
                            i = 0;
                    }
    
                    if( curr != ' '){
                            word[i] = tolower(curr);
                            i++;
                    } else {
                            word[i] = '\0';
                            i = 0;
    
                            for( j = 0 ; j < NUMRECORDS ; j++ ){
                                    if( strcmp(word, wordlist[j].word) == 0 ){
                                            wordlist[j].numTimesAppear += 1;
                                    }
                            }
                    }
    
                    val++;
                    curr = line[val];
            }
    
       }
    
       fclose(file);
       return 0;
    }
    
     
  19. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    Awesome, I'll mess with it some more. Thank you so much!

    I know about that bug with sorting, but if I sort the other way (low to high), I don't lose anything. It's really odd...

    Edit: Got it working! So if there was a null word in a sort, I just sorted the other way, and got the rest working by using ispunct() to get those words.

    Thank you again, so much for the help guys!
     
    Last edited: Apr 24, 2007
  20. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    Edit: Nevermind. The slides for the class were ambiguous.

    Now I'm working on core dumps. Yay!
     
    Last edited: Apr 30, 2007
  21. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    Sorry to bug you guys again!

    Ok, I'm totally stuck. I officially hate linked lists. There's got to be something very basic I'm just not getting here. So basically, I'm supposed to read in a small file from the command prompt with an id number, first, and last name of a student and use linked lists to manage the data. I'm reading the data fine, it's actually making the lists that I'm failing at.

    The problem is in the very last function, addStudent(). I've been messing with various printf() statements, and it's got to be there. I've attached a copy of the entire code, including the stupid class comments, and a sample file that's passed in from the command line. Thank you so much, again, for all the help guys!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "student.h"
    
    /* do not change any of the function prototypes
     */
    int processFile( char fn[ ], Student **cls );
    void printList( Student *class );
    void deleteEntry( Student **class );
    int addEntry( Student **class );
    void addStudent( Student **list, Student *newone );
    void freeList( Student **class );
    
    /* main function is complete, do not change
     */
    int main( int argc, char *argv[ ])
    { 
      Student *class = NULL;        // must initialize to NULL
      if ( argc != 2 )
      {
            printf( "Usage: %s filename\n", argv[0] );
            return -1;
      }
      if ( processFile( argv[1], &class ) )
      {
            printf( "ERROR on processing file\n" );
            return -3;
      }
      printList( class );
      char cmd = 'j', line[80];
      do
      {
            printf( "Options: p for print, d for delete an entry, a for add an entry, q for quit\n" );
            fgets( line, sizeof(line), stdin );
            sscanf( line, "%c", &cmd );
            switch( cmd )
            {
                    case 'p':
                            printList( class );
                            break;
                    case 'd':
                            deleteEntry( &class );
                            break;
                    case 'a':
                            if ( addEntry( &class ) )
                                    printf( "Could not add new entry.\n" );
                            break;
            }
      } while ( cmd != 'q' );
      freeList( &class );
      return 0;
    }
    
    /* Free up all the records in the list
     */
    void freeList( Student **class )
    {
      Student *temp = *class;
      while(temp != NULL)  {
        free(temp);
        temp = temp->next;
      }
    }
    
    
    // remove better
    
    void deleteEntry( Student **entries )
    {
      int delid;
      char line[80];
      Student *temp = *entries, *temp2=(Student*)malloc(sizeof(Student));
      printf( "Deleting entry: enter their ID number: " );
      fgets( line, sizeof(line), stdin );
      sscanf( line, "%d", &delid );
      while( temp != NULL)  {
        if(temp->next->id_num == delid) {
          temp2=temp->next;
          temp->next = temp2->next;
          free(temp2);
          break;
        }
      }
          
      if(temp2 == (Student*)NULL)
        printf("The file could not be found.\n");
    
      free(temp);
      // You must free up the memory of the deleted structure
    }
    
    int addEntry( Student **people )
    {
      // allocate memory for a new Student structure
      //  if error on allocation, print error msg and return negative value
      char line[81], first[15], last[15];
      int id;
    
      printf( "Enter the new first name, last name and id number separated with spaces\n" );
      fgets(line, sizeof(line), stdin );
      sscanf( line, "%s %s %d", first, last, &id );
        
      Student *st;
      st = (Student *)malloc(sizeof(Student));
      if (st == (Student *)NULL) {
        printf("ERROR on malloc - could not allocate enough memory.\n");
        return -2;
      }
      makeNewStudent(st, first, last, id);
      addStudent(people, st);
      
      free(st);
    
      return 0;
    }
    
    void printList( Student *roll )
    {
      while(roll != NULL)  {
        printf("\t%d\t%s\t%s\n",roll->id_num,roll->last,roll->fir);
        roll = roll->next;
      }
            // walk through list and print the 
            //   id, last name and first name separated with tabs
    }
    
    /* reads in the file and sets up the linked list
     * relies on other functions that you must write to get it to work
     * You must not change this function
     */
    int processFile( char fn[ ], Student **roster )
    {
       FILE *file;
       char line[81];
       file = fopen( fn, "r" );
       if ( file == NULL )
            return -3;
    
       char first[15], last[15];
       int id;
       Student *st;
       while( fgets(line, sizeof(line), file ) != NULL )
       {
            sscanf( line, "%s %s %d", first, last, &id );
            st = (Student *)malloc( sizeof(Student) );
            if ( st == (Student *)NULL )
            {
                    printf( "ERROR on malloc - could not allocate enough memory\n" );
                    return -2;
            }
            makeNewStudent( st, first, last, id );
            addStudent( roster, st );
       }
       fclose(file);
       
       free(st);
    
       return 0;
    }
    
    void addStudent( Student **list, Student *newone )
    {
      //  Student *class = *list, *temp;
      Student *temp;
      temp = (Student*)malloc(sizeof(Student));
      if(*list == NULL) {
        //    class = (Student*)malloc(sizeof(Student));
        strcpy(temp->fir,newone->fir);
        strcpy(temp->last,newone->last);
        temp->id_num = newone->id_num;
        temp->next = NULL;
      }
      else {
        strcpy(temp->fir,newone->fir);
        strcpy(temp->last,newone->last);
        temp->id_num = newone->id_num;
        temp->next = *list;
      }
      *list = temp;
    
            //      printf("%d %s %s\n",temp->id_num,temp->last,temp->fir);
            // if list is empty, make newone the first in the list
            // if list is not empty, make the new one the first one in the
            //      list and make sure it links to the rest of the list
    
      free(temp);
    }
    
    Student.h
    Code:
    #include <stdlib.h>
    
    typedef struct s_student {
      int id_num;
      char last[15];
      char fir[15];
      struct s_student *next;
    } Student ;
    
    void makeNewStudent( Student (*stu), char first[], char last[], int num);
    
    
    Student.c
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "student.h"
    
    void makeNewStudent( Student (*stu), char first[], char last[], int num) {
      stu->id_num = num;
      strcpy(stu->last,last);
      strcpy(stu->fir,first);
      stu->next = NULL;
    }
    
    
    Records:
    Code:
    Vague Person 1234
    Joe Shmoo 9890
    Gar Field 8300
    Queen Bee 1002
    
    
     
  22. skinjob

    skinjob Active Member

    Joined:
    Jan 6, 2001
    Messages:
    2,337
    Likes Received:
    0
    Location:
    Aztlán
    free(temp); == no list
     
  23. GOGZILLA

    GOGZILLA Double-Uranium Member

    Joined:
    Jan 16, 2003
    Messages:
    10,760
    Likes Received:
    3
    Location:
    Plantation, FL
    yeah dude in lists you cant free the memory that youve just allocated. if youre passing ownership of a malloc'd location to a data structure youre keeping track of there wont be a leak and you should just let that local pointer go out of scope.
     
  24. wytefyre

    wytefyre New Member

    Joined:
    May 30, 2005
    Messages:
    328
    Likes Received:
    0
    Wow, that was a really easy fix.

    The only reason I freed that memory, is they were making a big deal about freeing up malloc'd memory.

    Yay, I'm basically done with it now! Just gotta fix my deleting function a little more and it's done.

    Thank you so much guys! You totally rock!
     

Share This Page