-6

I am having a lot of trouble starting my project. Here are the directions:

"Complete counts.c as follows:
    Read characters from standard input until EOF (the end-of-file mark) is read. Do not prompt the user to enter text - just read data as soon as the program starts.
    Keep a running count of each different character encountered in the input, and keep count of the total number of characters input (excluding EOF)."

The format my professor gave me to start is: `

#include <stdio.h>
int main(int argc, char *argv[]) {
return 0;
}

In addition to how to start the problem, I'm also confused as to why the two parameter's are given in the main function when nothing is going to be passed to it. Help would be much appretiated! Thank you!

`

Sunil Bojanapally
  • 12,528
  • 4
  • 33
  • 46
user3321551
  • 123
  • 2
  • 3
  • 15

3 Answers3

2

Slightly tricky to see what you're having trouble with here. The title doesn't form a complete question, nor is there one in the body; and they seem to be hinting at entirely different questions.

The assignment tells you to read characters - not store them. You could have a loop that only reads them one at a time if you wish (for instance, using getchar). You're also asked to report counts of each character, which would make sense to store in an array. Given that this is of "each different character", the simplest way would be to size the array for all possible characters (limits.h defines UCHAR_MAX, which would help with this). Remember to initialize the array if it's automatically allocated (the default for function local variables).

Regarding the arguments to main, this program does not need them, and the C standard does allow you to leave them out. They're likely included as this is a template of a basic C program, to make it usable if command line arguments will be used also.

For more reference code you might want to compare the word count utility (wc); the character counting you want is the basis of a frequency analysis or histogram.

Yann Vernier
  • 15,414
  • 2
  • 28
  • 26
0

This should give you a start to investigate what you need to learn to complete your task,

Initially declare a character input buffer of sufficient size to read chars as,

char input[SIZE];

Use fgets() to read the characters from stdin as,

if (fgets(input, sizeof input, stdin) == NULL) {
     ;  // handle EOF
}

Now input array has your string of characters which you to find occurrence of characters. I did not understand When you say different characters to count, however you have an array to traverse it completely to count the characters you need.

Sunil Bojanapally
  • 12,528
  • 4
  • 33
  • 46
0

Firstly, luckily for you we will not need dynamic memory allocation at all here as we are not asked to store the input strings, instead we simply need to record how many of each ascii code is input during program run, as there a constant and finite number of those we can simply store them in a fixed size array.

The functions we are looking at here (assuming we are using standard libs) are as follows:

  • getchar, to read chars from standard input
  • printf, to print the outputs back to stdout

The constructs we will need are:

  • do {} while, to loop around until a condition is false

The rest just needs simple mathematical operators, here is a short example which basically shows a sample solution:

#include <stdio.h>
int main(int argc, char *argv[])
{
    /* Create an array with entries for each char,
     * then init it to zeros */
    int AsciiCounts[256] = {0};
    int ReadChar;
    int TotalChars = 0;
    int Iterator = 0;
    do
    {
        /* Read a char from stdin */
        ReadChar = getchar();
        /* Increment the entry for its code in the array */
        AsciiCounts[ReadChar]++;
        TotalChars++;
    } while (ReadChar != EOF);
    /* Stop if we read an EOF */
    do
    {
        /* Print each char code and how many times it occurred */
        printf("Char code %#x occurred %d times\n", Iterator, AsciiCounts[Iterator]);
        Iterator++;
    } while (Iterator <= 255);
    /* Print the total length read in */
    printf("Total chars read (excluding EOF): %d", --TotalChars);
    return 0;
}

Which should achieve the basic goal, however a couple of extension exercises which would likely benefit your understanding of C. First you could try to convert the second do while loop to a for loop, which is more appropriate for the situation but I did not use for simplicity's sake. Second you could add a condition so the output phase skips codes which never occurred. Finally it could be interesting to check which chars are printable and print their value instead of their hex code.

On the second part of the question, the reason those arguments are passed to main even though they are ignored is due to the standard calling convention of c programs under most OSes, they pass the number of command line arguments and values of each command line argument respectively in case the program wishes to check them. However if you really will not use them you can in most compilers just use main() instead however this makes things more difficult later if you choose to add command line options and has no performance benefit.

Vality
  • 6,577
  • 3
  • 27
  • 48
  • Please don't just hand complete solutions to homework. By the way, why split a for loop onto separate lines, one of which is left on the other side of another loop? – Yann Vernier Feb 19 '14 at 09:37
  • Sorry, I was assuming from the question that the asker has 0 programming experience so thought a carefully explained answer along with some extensions would be helpful for him to study (it seems he does not have the experience to start from scratch at this stage) but if you disagree on the matter feel free to edit the answer to be less complete. Though I don't really understand what you mean by splitting a loop, I code to "Allman style" indentations as is the defacto standard of my work place. – Vality Feb 19 '14 at 10:14
  • I don't mean the indentation. I mean the loop handling Iterator, which ordinarily would be written using `for(int i=0; i<=UCHAR_MAX; i++) { printf(...); }` rather than a do..while. – Yann Vernier Feb 19 '14 at 17:42
  • Oh, I actually explain that in the answer, if you read: " First you could try to convert the second do while loop to a for loop, which is more appropriate for the situation but I did not use for simplicity's sake." – Vality Feb 19 '14 at 17:44
  • It says simplicity (sorry for not reading thoroughly earlier). I just don't see it as simpler; it seems merely less clear, though it can be argued to be more consistent since there's only one type of loop. – Yann Vernier Feb 19 '14 at 17:46
  • That is the idea, I wanted to explain every construct I was going to use due to the seeming complete beginner status of the asker and thus wanted to use as few as possible. However if you would rather remove the comment on simplicity and make it a for instead, I dont really mind. – Vality Feb 19 '14 at 17:48
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/47886/discussion-between-vality-and-yann-vernier) – Vality Feb 19 '14 at 17:51