简体   繁体   中英

How do I make my C program count more than just one character?

I'm trying to write a program that takes a file and a string by using Standard C functions, the program counts all the characters in the file which the string contains.

For example if the user writes:

counter.exe x.txt abcd

The program calculates the number of each character that the string contains: a, b,c,d in file x.txt

Sample message:

Number of 'a' characters in 'x.txt' file is: 12
Number of 'b' characters in 'x.txt' file is: 0
Number of 'c' characters in 'x.txt' file is: 3
Number of 'd' characters in 'x.txt' file is: 5

So far I've been able to make it print and count one character from the file, how do I make it count all the characters that I tell it to count, not just the first one from the string?

counter.c code:

#include<stdio.h>

int main() {

    int count = 0;
    char sf[20]; char rr; FILE* fp; char c;

    printf("Enter the file name :\n");
    gets(sf);

    printf("Enter the character to be counted :\n");
    scanf("%c", &rr);
    fp = fopen(sf, "r");

    while ((c = fgetc(fp)) != EOF)
    {
        if (c == rr)
            count++;
    }
    printf("File '%s' has %d instances of letter '%c'.", sf, count, rr);

    fclose(fp);
    return 0;
}

#define  SIZE 1024
char * malloc_buff(int dim){
    char *buf;
    buf=malloc(sizeof(char)*dim);
    if(buf==NULL){
        perror("Error in malloc");
    }
    return buf;
}


char * read_file(char * file){
    FILE* fd;
    char* file_pt;
    file_pt=malloc_buff(SIZE);
    errno=0;
    fd=fopen(file,"r+");
    if(errno!=0){
        fprintf(stderr,"error open file\n");
        exit(-1);
    }
    fread(file_pt,sizeof(char),SIZE,fd);
    if(fclose(fd)){
        fprintf(stderr,"errore close file\n");
        exit(-1);
    }
    return file_pt;
}
int main(int argc, char *argv[])
{
    char* content;
    content=malloc_buff(SIZE);
    content=read_file(argv[1]);
    int lenght_word=strlen(argv[2]);
    int counter[lenght_word];
    int i=0,x=0;
    for(x=0;x<lenght_word;x++){
        counter[x]=0;
    }
    while (content[i]!='\0'){
        for(x=0;x<lenght_word;x++){
            if (content[i]==argv[2][x]){
                counter[x]++;
            }
        }
        i++;
    }
    for(x=0;x<lenght_word;x++){
        printf("The values are: for %c is %d",argv[2][x],counter[x]);
    }
    return 0;
}

Several solutions:

  1. Give some inputs to your main() function and parse these, see here
  2. Do another while loop where you place the scanf() and the other while loop (and the other stuff you need).
  3. If you want, for example, 4 letters, then implement a for loop and place the scanf() in it, storing the values in an array. Then you'll have to add 4 different counters that you update in 4 different tests within the next while loop.

By the way if you need this program for other purpose than just an exercise, there is lots of already implemented commands in your system that can do it, like grep .

You can use strpbrk and a lookup table:

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

int main(void) 
{
    char *text = "Sample input bla bla bla"; // your file contents
    const char *find = "abcd"; // your argv[2]
    int lookup[127] = {0}; // the lookup table

    while (*text)
    {
        char str[2] = {*text, 0};
        char *ptr = strpbrk(str, find);

        if (ptr != NULL) // if found
        {
            if ((*ptr >= 0) && (*ptr < 128))
            {
                lookup[(int)*ptr]++; // increase position
            }
        }
        text++;
    }
    for (int i = 0; i < 128; i++)
    {
        if (lookup[i] != 0)
        {
            printf("%c: %d times\n", i, lookup[i]);
        }
    }
    return 0;
}

Output:

a: 4 times
b: 3 times

I'll assume that you can read the file into either a single large buffer or a line at a time into a smaller buffer.

void  CountChars( unsigned int *charCount, char *buffer, int bufferSize )
{
    unsigned int  i;

    for (i = 0; i < bufferSize; i++) {
        charCount[buffer[i]]++;
    }
}

void main( int argc, char **argv )
{
    unsigned int  charCount[256];
    int           i;
    char          buffer[8192];  /* Or whatever size you want to work with at a time */

    /* Initialize the character counts to zero */
    memset(charCount, 0, sizeof(charCount));

    /* Insert code to fill the buffer with the file data */

    /* Count the characters in the buffer */
    CountChars(charCount, buffer, sizeof(buffer));

    /* At that point, the array 'charCount' has the count of each byte that
       occurred in the buffer.  If the file is too large to fit in memory
       and you called it in the loop, then you only initial the charCount
       array to zero before the first call.  From this point, you can go
       through the loop to determine which of the character counts you might
       be interested in, or if you are interested in all the characters that
       occurred, you could do the following. */
    for (i = 0; i < sizeof(charCount) / sizeof(charCount[0]); i++) {
        if (charCount[i] > 0) {
            printf("'%c' -- %d\n", (char) i, charCount[i]);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM