如何让我的 C 程序计数不止一个字符?

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

我正在尝试编写一个程序,使用标准 C 函数获取一个文件和一个字符串,该程序计算字符串包含的文件中的所有字符。

例如,如果用户写:

counter.exe x.txt abcd

程序计算字符串包含的每个字符的数量:文件中的a、b、c、d x.txt

示例消息:

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

到目前为止,我已经能够让它打印并计算文件中的一个字符,如何让它计算我告诉它计算的所有字符,而不仅仅是字符串中的第一个字符?

counter.c代码:

#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;
}

几种解决方案:

  1. 为您的 main() 函数提供一些输入并解析这些,请参阅 here
  2. 在放置 scanf() 和另一个 while 循环(以及您需要的其他东西)的地方做另一个 while 循环。
  3. 例如,如果您想要 4 个字母,则实现一个 for 循环并将 scanf() 放入其中,将值存储在数组中。然后你必须添加 4 个不同的计数器,你在下一个 while 循环中的 4 个不同的测试中更新它们。

顺便说一下,如果您需要此程序用于其他目的而不仅仅是练习,您的系统中有许多已经实现的命令可以执行此操作,例如 grep

您可以使用 strpbrk 和查找 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;
}

输出:

a: 4 times
b: 3 times
#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]!='[=10=]'){
        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;
}

我假设您可以将文件读入单个大缓冲区或一次将一行读入较小的缓冲区。

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]);
        }
    }
}