文件中的字符重复 - 不区分大小写

时间:2017-07-18 06:46:59

标签: c string file pointers

我写了一个程序来计算文件中的字符数。我打算让程序不区分大小写。但是我收到的错误如下所示。

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

int main() {
    FILE *fp1;
    char c[100], f[20], k;
    int count = 0;

    printf("Enter the file name\n");
    scanf("%s", f);

    printf("Enter the character to be counted\n");
    scanf(" %c", &k);

    fp1 = fopen(f, "r");

    while (fscanf(fp1, "%c", c) != EOF) {
        if (strcmpi(c, k) == 0)
            count++;
    }

    fclose(fp1);

    printf("File '%s' has %d instances of letter %c", f, count, k);
    return 0;
}

在这个程序中,我收到一条错误

warning: passing argument 2 of 'strcmpi' makes pointer from integer without a cast [-Wint-conversion]

我该怎么做才能纠正它?

4 个答案:

答案 0 :(得分:1)

您的代码中存在多个问题:

  • char f[20];对于许多文件名来说可能太短了。
  • 您应该通过提供存储到数组中的最大字符数来防止scanf()中的缓冲区溢出:scanf("%19s", f);
  • 如果转换失败,您应该测试scanf()返回值以避免未定义的行为。
  • 您应该测试fopen是否成功。
  • 您应该通过char的标准函数strcmpi将字符转换为小写,而不是将tolower值传递给非标准函数<ctype.h>

    if (tolower((unsigned char)k) == tolower((unsigned char)c[0]))
        count++;`
    

    char的{​​{1}}参数转换为tolower,以避免传递未定义行为的潜在负值。

以下是更正后的版本:

(unsigned char)

注意:

  • 文件名#include <ctype.h> #include <stdio.h> int main(void) { FILE *fp; char f[1024], k; int lower_k, c; int count = 0; printf("Enter the file name: "); if (scanf("%1023s", f) != 1) return 1; printf("Enter the character to be counted: "); if (scanf(" %c", &k)) != 1) return 1; fp = fopen(f, "r"); if (fp == NULL) { printf("cannot open file '%s'\n", f); return 1; } lower_k = tolower((unsigned char)k); while ((c = getc(fp)) != EOF) { if (tolower(c) == lower_k) count++; } fclose(fp); printf("File '%s' has %d instances of letter %c\n", f, count, k); return 0; } 不能包含空格。
  • 无法使用此程序计算空格字符,因为f会跳过它们,直到您键入非空格字符为止。

考虑使用scanf(" %c", &k)来阅读输入并修复这些缺点。

编辑如果您想要或必须使用函数fgets(),您应该将字符读入2字节数组,其第二个字节是空字节,以使这些数组正确的字符串传递至strcmpi,但此解决方案非常低效

strcmpi

答案 1 :(得分:0)

strcmpi需要两个指向字符串的指针。但你通过值传递k。那是char

char c[100], f[20], k;
// ...
    if(strcmpi(c,k)==0)  count++;
//...
// fix:
    if(strcmpi(c,&k)==0)  count++;

您应该考虑使用符合POSIX的_stricmp而不是strcmpi。

答案 2 :(得分:0)

您甚至不需要使用strcmpi()字符来直接比较两个字符:

if(tolower(c) == tolower(k))  
  count++; 

答案 3 :(得分:0)

要对不区分大小写的字符进行比较,只需使用tolower()toupper()将它们转换为相同的大小写。

#include<stdio.h>
#include<ctype.h>

int main()
{
    FILE *fp1;
    char f[20], k;
    int c;
    int count = 0;

    printf("Enter the file name\n");
    scanf("%s",f);

    printf("Enter the character to be counted\n");
    scanf(" %c",&k);
    int k_int = tolower((unsigned char)k);        

    fp1 = fopen(f,"r");

    while((c = fgetc(fp1)) != EOF)
    {
        if(tolower(c) == k_int) {
            count++;
        }
    }

    fclose(fp1);

    printf("File '%s' has %d instances of letter %c\n", f, count, k);
    return 0;
}