1

So what the program should basically do is we input filename -i input.txt -o output.txt -c in the command line (command line arguments (argc and argv)) and the program should read the inputfile, count how many words there are, and if there is -c it should convert all of uppercases to lowercases and ignore punctuation. And then count the occurrences of every word and output the result in the ouput.txt. If there is no -i input.txt it should prompt for input from user and do the same and if there is no -o output.txt it should print the output in the compiler. So what's not working from my program is if(argc == 4), if(argc == 3). I don't have the function for wordOccurrences for now. I know that the header "count.h" should't be like a header but for now it works.

MAIN FILE

#include "count.h"
#include <stdio.h>``
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "functions.c"

int main(int argc, char **argv)
{   
    //Initialize variables
    FILE *fp; //file        
    char buffer[1000];

    char *input; //for manually entering string with -c
    input = (char*)malloc(100 * sizeof(char));

    int wordcount; // the number of words

    int *ch; //a single character
    ch = (int*)malloc(100000 * sizeof(int));

    char consoleInput[60];

    if(argc >=2)
    {       
        if(argc == 6) //if argc = 5 --> wordcount -i .txt -o .txt -c
        {       
            //for (int i=0; i<=argc; i++)
            //{ 
            // if line has -i
            if (strcmp("-i", argv[1]) == 0)
            {
                //open file on directory after -i
                fp = fopen(argv[2],"r");

                //do wordcount method
                wordcount = countForFile(fp, wordcount);

                //close file
                fclose(fp);
            }// end of first if

            // if line has -o
            if(strcmp("-o", argv[3]) == 0)
            {
                //open file on directory after -o
                fp = fopen(argv[4], "w");

                //put wordcount in file
                fprintf(fp,"%d", wordcount);
                printf("Putting output to file\n");

                //close file
                fclose(fp);
            } // end of second if

            //if line has -c
            if(strcmp("-c", argv[5]) == 0)
            {
                //open file on location 2
                fp = fopen(argv[2],"r");

                // do toLowerCase method
                toLowerCase(fp,ch);

                //open file on location 2
                fp = fopen(argv[2],"r");

                //count occurances

                printf("Well countOccurances is in process\n");

                //close file
                fclose(fp);

            } //end of third if

            //}
        }
        if (argc == 5) // if argc = 4 --> wordcount -i .txt -o .txt 
        {
            //for (int i=0; i<=argc; i++)
            //{ 
            // if line has -i
            if (strcmp("-i", argv[1]) == 0)
            {
                //open file on directory after -i
                fp = fopen(argv[2],"r");

                //do wordcount method
                wordcount = countForFile(fp, wordcount);

                //close file
                fclose(fp);
            }// end of first if

            // if line has -o
            if(strcmp("-o", argv[3]) == 0)
            {
                //open file on directory after -o
                fp = fopen(argv[4], "w");

                //put wordcount in file
                fprintf(fp,"%d", wordcount);
                printf("Putting output to file\n");

                //close file
                fclose(fp);

            } // end of second if
            //}
        }
        else if(argc == 4) // if argc = 3 -> wordcount -i txt -c; wordcount -o txt -c
        {
            //for (int i=0; i<=argc; i++)
            //{
            if(strcmp("i",argv[1]) == 0)
            {
                printf("first i if working\n"); 
                if(strcmp("i",argv[1]) == 0)
                {
                    //open file on directory after -i
                    fp = fopen(argv[2],"r");

                    //do wordcount method
                    wordcount = countForFile(fp, wordcount);

                    //close file
                    fclose(fp);
                    printf("I if working\n");
                }
                //if line has -c
                if(strcmp("-c", argv[3]) == 0)
                {
                    //open file on location 2
                    fp = fopen(argv[2],"r");

                    // do toLowerCase method
                    toLowerCase(fp,ch);

                    //open file on location 2
                    //fp = fopen(argv[2],"r");

                    //count occurances

                    printf("Well countOccurances is in process\n");

                    //close file
                    fclose(fp);

                } //end of third if
            }
            else if(strcmp("-o",argv[1]) == 0)
            {
                printf("Enter q to exit\n");
                printf("Enter text: ");
                wordcount = count(input, wordcount);

                if(strcmp("-o", argv[1]) == 0)
                {
                    //open file on directory after -o
                    fp = fopen(argv[2], "w");

                    //put wordcount in file
                    fprintf(fp,"%d", wordcount);
                    printf("Putting output to file\n");

                    //close file
                    fclose(fp);
                } // end of second if

                //if line has -c
                if(strcmp("-c", argv[3]) == 0)
                {
                    //open file on location 2
                    fp = fopen(argv[2],"r");

                    // do toLowerCase method
                    toLowerCase(fp,ch);

                    //open file on location 2
                    fp = fopen(argv[2],"r");

                    //count occurances

                    printf("Well countOccurances is in process\n");

                    //close file
                    fclose(fp);

                } //end of third if
            }
            //}
        }   

        if(argc == 3) // if argc = 2 -> wordcount -i txt; wordcount -o txt
        {
            //for (int i=0; i<=argc; i++)
            //{
            if(strcmp("i",argv[1]) == 0)
            {
                //open file on directory after -i
                fp = fopen(argv[2],"r");

                //do wordcount method
                wordcount = countForFile(fp, wordcount);

                //close file
                fclose(fp);
                printf("PLS WORK\n");
            }   
            else if(strcmp("-o", argv[1]) == 0)
            {
                printf("Enter q to exit\n");
                printf("Enter text: ");
                wordcount = count(input, wordcount);

                //open file on directory after -o
                fp = fopen(argv[2], "w");

                //put wordcount in file
                fprintf(fp,"%d", wordcount);
                printf("Putting output to file\n");

                //close file
                fclose(fp);
            } // end of second if
            //}
        }
        if(argc == 2) //wordcountMain -c
        {
            //for (int i=0; i<argc; i++)
            //{
            //converting from UpperCase to LowerCase
            if(strcmp("-c", argv[1]) == 0)
            {   
                //Get input
                printf("Enter text: ");
                fgets(input,1000,stdin);

                int i = 0;
                //Loop through input
                for( i = 0;input[i]!='\0'; i++) 
                {
                    //find upperCase letters
                    if(input[i] >= 'A' && input[i] <= 'Z')
                    {
                        //overwrite to lowerCase
                        input[i] = tolower(input[i]);

                        //input[i] = input[i] +32;
                        printf("Converted upperCase to lowerCase\n");

                    }//end of if statement  

                    //ignoring punctuation  
                    if(input[i] == ',' || input[i] == '.' || input[i] == '!' || input[i] == '?' || input[i] == '"' || input[i] == ':' || input[i] ==';' || input[i] == '-')
                    {
                        input[i] = ' ';
                        printf("Converted without punctuation\n");
                    }
                } //end of for loop

                printf("%s",input);
            }
            //}
        }
    }
    else
    {
        //Get input
        printf("Enter text: ");
        //fgets(input,1000,stdin);
        wordcount = count(input, wordcount);
        printf("%s",input);
        wordcount = count(input, wordcount);
    }
    return 0;
}

count.h

# pragma once
// This file needs to know what printf is
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

//count how many words for read file
int countForFile(FILE *file, int wordcount)
{
    int ch;
    int linecount, charcount;


     // Initialize counter variables
     linecount = 0;
     wordcount = 0;
     charcount = 0;


   // If file opened successfully, then write the string to file
   if ( file )
   {
       //Repeat until End Of File character is reached. 
       while ((ch=getc(file)) != EOF) {
          // Increment character count if NOT new line or space
            if (ch != ' ' && ch != '\n') { ++charcount; }

          // Increment word count if new line or space character
           if (ch == ' ' || ch == '\n') { ++wordcount; }

          // Increment line count if new line character
           if (ch == '\n') { ++linecount; }

        }
    }
   else
    {
        printf("Failed to open the file\n");
    }
    printf("Words : %d \n", wordcount);

    getchar();
    return wordcount;
}

/*
    Hello, Bye, Hello;

    int index = 2;
    String[] words = [Hello, Bye, null];
    int [] count = [2, 1, 0,];
*/
int count(char *input, int wordcount)
{   
    wordcount = 0;
    while(scanf("%s",input) != EOF)
                {
                    if(input[0] == 'q' && strlen(input) == 1)
                        break;
                    wordcount++;

                }// end of while loop

                printf("WordCount is: %d\n", wordcount);
    getchar();
    return wordcount;
}

function.h

#include "count.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

//Check for UpperCase and turn into LowerCase for a read file
toLowerCase(FILE *fp,int *ch)
{
    //Initialize variables
    int single_character;
    int i =0;

    //if file is read
    if ( file )
    {
       //Repeat until End Of File character is reached. 
       while ((single_character=getc(fp)) != EOF)
        {
            //check every single character if it's a upperCase
            if(single_character >= 'A' && single_character <= 'Z')
            {
                //if it is overwrite it to lowerCase
                single_character = tolower(single_character); //overwrite
            }   
            ch[i] = single_character;
            i++;
        } //end while   
    } //end if

   //if file not opened 
   else
    {
     printf("Error: File not opened\n");  
    } //end else    

    getchar();

    printf("toLowerCase Working\n");

} // end toLowerCase

So Yeah i would appreciate any help. I am new to C and if you have another idea for how i should make the program work post your ideas. Anything would help really.

Barmar
  • 741,623
  • 53
  • 500
  • 612

2 Answers2

0

You can try this:

if(argc >= 2){
  switch(argc){
    case 3: //Some code
           break;
    case 4: //Some code
           break;
    case 5: //Some code
           break;
    //...
  }
}
Nitre
  • 1
  • 3
0

I would do something like this:

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>


int main(int argc, char const *argv[]) {

    char *input_file = NULL;
    char *output_file = NULL; 

    unsigned int threshold = 0;

    unsigned int wordcount = 0;

    int c;

    while(1) {
        static struct option long_options[] = {
            {"input_file", required_argument, 0, 'i'},
            {"output_file", required_argument, 0, 'o'},
            {"threshold", required_argument, 0, 'c'},
            {0, 0, 0, 0}
        };
        /* getopt_long stores the option index here. */
        int option_index = 0;

        c = getopt_long (argc, argv, "iot",
                         long_options, &option_index);

        // Detect the end of the options

        if(c == -1)
            break;

        switch(c) {
            case 'i':
                input_file = optarg;
                break;
            case 'o':
                output_file = optarg;
                break;
            case 'c':
                threshold = atoi(optarg);
                break;
            case '?':
                /* getopt_long already printed an error message. */
                break;

            default:
                abort ();           
        }



    }

    if (input_file == NULL || output_file == NULL || threshold == 0) {
        fprintf(stderr, "ERROR, Usage: %s -input_file=<fileName> -output_file=fileName -threshold=<value>\n", argv[0]);
        return 1;
    }

    // NOW input_files, outpuf_files and threshold contain the wanted values
    // The real algorithm begins


    FILE *fp = fopen(input_file, "r");

    //calculate filesize (limits the size of file to s32 bytes)
    unsigned int fileSize = 0;
    fseek(fp, 0L, SEEK_END);
    fileSize = ftell(fp);
    rewind(fp);

    char *file = malloc(fileSize * sizeof(char));

    fread(file, sizeof(char), fileSize, fp); // WARNING: ALLOCATING MEMORY FOR THE WHOLE FILE
                                             // FOR BIG FILES CONSIDER USING A BUFFER

    for (int i = 0; i < fileSize; ++i) {
        if(file[i] == ' ' || file[i] == '\n')
            wordcount++;

    }
    wordcount++; //counting last word;

    return 0;
}

In this example i am using the getopt library to parse the command line arguments (the argv array). This program should be called like this: ./programName --input_file="filename" --output_file="filename" --threshold=value

Furthermore i notice that you cast the return value of the memory allocations functions. In the C programming language this is usually considered bad practice, for more information see here.

My program is not complete and does not contain any logic, that part you should try to do alone (you can always ask if you don't know how to implement some parts of the algorithm).

I would also like to spend some words on how to read data from a file. Usually you want to avoid to do something like what i did (allocating an array containing the whole file) because when working with big files the memory requirements becomes prohibitive. On the other hand you are doing the opposite: you are retrieving 1 byte (or character) at a time and you are immediately using its value in your calculations. This causes your program to become very slow when the file size increases. This is because an I/O operation on a file is a very time-demanding task. There is no "right" solutions, it all depends from the situation: if you know that the file size doesn't get too crazy high (order of 10^2 MB)and main memory (RAM) is not a problem then maybe you should to do something similar to what i did. If file size can get very big then you should probably using a buffer (in this specific case it would make the program very complicated). All this problems arises when file sizes get really big, if you know they wont then my approach is generally faster and has no real contraindication.