1

I need to read a line from a file, find the biggest word in the line, read the next word. Seems simple enough. I'm new to C so I know I'm probably missing something easy. If I don't include '\n' as a delimiter it will print the blank lines in the file (lines between paragraphs), and will print a new line if the biggest word is at the end of the line. If I do include it the token will repeat if there is a blank line after it, and the last line in the file is skipped. Here is the code:

#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUFFSIZE 81

int main(int numParms, char *parms[])
{
    FILE *file;
    char buffer[BUFFSIZE];
    char *token;
    int lineNum = 0;
    int currSize = 0;


   file = fopen("in.txt" , "r");
   if(file == NULL) 
   {
        perror("Error opening file");
        return(-1);
   }
   fgets(buffer, BUFFSIZE, stdin);
   while(!feof(stdin)) 
   {    
        char bigWord[30];
        char currWord[30];
        int bigSize = 0;

        lineNum++;
        token = strtok(buffer, " \n\t");
        while(token != NULL)
        {               
            strcpy(currWord, token);
            currSize = strlen(currWord);
            if(currSize > bigSize && currSize != bigSize)
            {
                strcpy(bigWord, currWord);
                bigSize = strlen(bigWord);
            }
            token = strtok(NULL, " \n\t");  
        }
    printf("Line %d's word: %s\n", lineNum, bigWord);

    fgets(buffer, BUFFSIZE, stdin);
    }

   fclose(file);

   return(0);
}
molnarb
  • 13
  • 3
  • FYI `if(currSize > bigSize && currSize != bigSize)` is redundant since if `currSize > bigSize` is true, then certainly `currSize != bigSize` is true. And you keep looping on the last token because `!feof(stdin)` is the wrong way to determine if your input is done. There are many posts on SO about that. See for example: [“while( !feof( file ) )” is always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) and [Why it's bad to use feof() to control a loop](http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1046476070&id=1043284351). – lurker Oct 02 '14 at 23:40
  • (unfortunately) feof() usage is correct in this case. (it is still overly complex) – wildplasser Oct 02 '14 at 23:57
  • @wildplasser `feof()` usage is some what OK. OP's style does not catch IO errors. Would need `while(!feof(stdin) && !ferror(stdin))`. Agree about over-complication, checking the result of `fgets()` is much simpler. – chux - Reinstate Monica Oct 03 '14 at 03:11
  • Fully agree. I don't understand *why* people get taught idioms like this. Maybe a teacher that was raised in the Pascal - era? – wildplasser Oct 03 '14 at 07:31
  • I included currSize != bigSize because if two words are the same length I want the first one in the line @lurker . As for error checking I am still fairly new to C, only been using it for a couple weeks and we are just starting to go over it in class, but yes it is good programming practice to include it – molnarb Oct 04 '14 at 17:34

1 Answers1

0
  1. Uninitialized buffer.

    Whenever fgets() reads a line made up of only ' ', '\n', or '\t', printf("... %s\n", ..., bigWord); prints the unitalicized bigWord, which simple may have the contents of the previous line parsing.

  2. OP opens file, but uses stdin. @BLUEPIXY

Some improvements

// improved fgets() usage,  catches IO error, unlike before
while (fgets(buffer, BUFFSIZE, file) != NULL) {
  char bigWord[BUFFSIZE]; // Worst case size
  bigWord[0] = '\0';  // Initialize bigWord
  size_t bigSize = 0;  // type int is OK for small buffers, but size_t is best

  lineNum++;
  char *token = strtok(buffer, " \n\t"); // local declaration
  while(token != NULL) {               
    char currWord[BUFFSIZE]; // local declaration
    strcpy(currWord, token);
    size_t currSize = strlen(currWord);  // local declaration

    // Drop 2nd part of if() - not needed
    // if(currSize > bigSize && currSize != bigSize) {
    if(currSize > bigSize) {
      strcpy(bigWord, currWord);
      bigSize = strlen(bigWord);  // or just use bigSize = currSize
    }
    token = strtok(NULL, " \n\t");  
  }
  printf("Line %d's word: `%s`\n", lineNum, bigWord);  // added ``
}

Other simplifications possible:
No need for char currWord[BUFFSIZE], just use token.

Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • @BLUEPIXY Updated per your keen eye. Totally missed the `file` vs. `stdin`. – chux - Reinstate Monica Oct 03 '14 at 13:23
  • Your answer was great, except that it still prints the blank lines in the file. – molnarb Oct 04 '14 at 20:31
  • @molnarb True about blank lines in the file. But your post never said it did not want to print the blank lines. "I need to read a line from a file, find the biggest word in the line" sounds like if the biggest word is `""`, then print that. This is not so much an issue about semantics, but a good lesson in defining software: not only should the main goal get defined, but also the edge cases and exceptional ones too. – chux - Reinstate Monica Oct 04 '14 at 22:06