Home > database >  Parsing every word
Parsing every word

Time:12-09

My program reads a txt file and can print all the contents one by one to the console but I have to store every variable in a different string and then print them out seperatly to the console.

Expected output is :

///////////
First word: Grep
Second word: danger
Third word: <
////////////  
First word: ls
Second word: -a
Third word : -
/////////

Output of the program:

 grep
 danger
 <
ls
-a
-

Input file content:

grep danger <
ls -a wc hw2 . c >
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <ctype.h>

#include <sys/types.h>

#include <sys/stat.h>

int main(int argc, char* argv[])
{
    FILE * file;
    file = fopen("commands.txt","r");
    char *token;
    const char s[2] = " ";
    
    fseek(file,0,SEEK_END);
    int length = ftell(file);
    fseek(file,0,SEEK_SET);
    
    char*string = malloc(sizeof(char) * (length 1));
    
    char c;
    int i = 0 ;
    
    while( (c= fgetc(file)) != EOF) {
        string[i]=c;
        i  ;
    }
   
    string[i]='\0';
    
    token = strtok(string, s);
    while( token != NULL ) {
        printf( " %s\n", token );
        token = strtok(NULL, s);
    }
    
    return 0;
}

CodePudding user response:

I suggest that you create a loop which reads and processes one line at a time. In order to read a single line at once, you can use the function fgets. This is easier than reading a single character at a time using fgetc.

You can define an array which maps the numbers 1 to 10 to the individual string literals "First", "Second", "Third", etc:

const char *map[] = {
    "Zeroth",
    "First", "Second", "Third", "Fourth", "Fifth",
    "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"
};

Now you can then change the lines

while( token != NULL ) {
    printf( " %s\n", token );
    token = strtok(NULL, s);
}

to:

for ( int i = 1; i < 11 && token != NULL; i   ) {
    printf( "%s word: %s\n", map[i], token );
    token = strtok(NULL, s);
}

That way, it will print:

First word: Grep
Second word: danger
Third word: <

After making these changes, your program should look like this:

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

#define NUM_MAPPINGS 11

int main( void )
{
    FILE *file;
    char line[200];
    char *token;
    const char *delimiter = " ";
    const char *separator = "///////////";

    const char *map[NUM_MAPPINGS] = {
        "Zeroth",
        "First", "Second", "Third", "Fourth", "Fifth",
        "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"
    };

    //attempt to open file
    file = fopen( "commands.txt", "r" );
    if ( file == NULL )
    {
        fprintf( stderr, "Error opening file!\n" );
        exit( EXIT_FAILURE );
    }

    //print separator
    printf( "%s\n", separator );

    //process one line per loop iteration
    while ( fgets( line, sizeof line, file ) != NULL )
    {
        //remove newline character from input, if it exists
        line[strcspn(line,"\n")] = '\0';

        //find first token
        token = strtok( line, delimiter );

        for ( int i = 1; i < NUM_MAPPINGS && token != NULL; i   )
        {
            //print current token
            printf( "%s word: %s\n", map[i], token );

            //find next token
            token = strtok( NULL, delimiter );
        }

        //print separator
        printf( "%s\n", separator );
    }

    //cleanup
    fclose( file );
    
    return 0;
}

For the input specified in the question, this program has the following outptu:

///////////
First word: grep
Second word: danger
Third word: <
///////////
First word: ls
Second word: -a
Third word: wc
Fourth word: hw2
Fifth word: .
Sixth word: c
Seventh word: >
///////////

CodePudding user response:

Good answer...

I expanded it a bit :)

#include <stdio.h>
#include <stdint.h>

void my_print(int num, char *s)
{
  char level_0[19][12] =
  {
    "First",
    "Second",
    "Third",
    "Forth",
    "Fifth",
    "Sixth",
    "Seventh",
    "Eighth",
    "Nineth",
    "Tenth",
    "Eleventh",
    "Twelveth",
    "Thirteenth",
    "Forteenth",
    "Fifteenth",
    "Sixteenth",
    "Seventeenth",
    "Eighteenth",
    "Nineteeth"
  };

  char level_1[8][7] =
  {
    "Twent",
    "Thirt",
    "Fort",
    "Fift",
    "Sixt",
    "Sevent",
    "Eight",
    "Ninet"
  };

  if (num < 20)
  {
    printf("%s word: %s\n", level_0[num - 1], s);
  }

  else if (num % 10 == 0)
  {
    printf("%sieth word: %s\n", level_1[num/10 - 2]);
  }

  else
  {
    printf("%sy-%s word: %s\n", level_1[num/10 - 2], level_0[num - 1], s);
  }

}

int get_token(FILE *fp, char *s, int max_length)
{
  char c;
  int counter = 0;

  s[0] = '\0';

  while (!feof(fp))
  {
    if (counter == max_length) { return -2; }

    c = getc(fp);

    if (c == ' ') { return 1; }
    if (c == '\n') { return 2; }
    *s = c;
    s  ;
    *s = '\0';
    counter  ;
  }

  return -1;
}

int main(int argc, char *argv[])
{
  if (argc != 2)
  {
    printf("Arguments Error.\nUsage: parse_words [filename].\n");
    
    return 1;
  }

  const char *fname = argv[1];
  FILE *fp;
  char token[80];
  size_t len = 80;
  int word_count = 0;
  int get_token_state;

  fp = fopen(fname, "r");

  if (fp == NULL)
  {
    printf("Error opening file %s!\n", fname);
    
    return 1;
  }

  printf("///////////\n");

  while ((get_token_state = get_token(fp, token, len)) != -1)
  {
    if (get_token_state == -2)
    {
      printf("Warning, overflow near %s\n.", token);
    }

    else if (get_token_state == 1)
    {
      word_count  ;
      my_print(word_count, token);
    }

    else if (get_token_state == 2)
    {
      word_count  ;
      my_print(word_count, token);
      word_count = 0;
      printf("///////////\n");
    }
  }

  fclose(fp);

  return 0;
}
  •  Tags:  
  • c
  • Related