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

C 文件中的字符重复-不区分大小写,c,string,file,pointers,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 th

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

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

我能做些什么来更正它呢?

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

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

你也许应该考虑使用POSIX兼容的StRMPMP代替StrucMPi。

< P>你不需要使用<代码> StcMcIf()/Cyto>字符,你可以直接通过以下方式比较两个字符:

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

要不区分大小写地比较字符,只需使用
tolower()
toupper()
将它们转换为同一大小写即可

#包括
#包括
int main()
{
文件*fp1;
charf[20],k;
INTC;
整数计数=0;
printf(“输入文件名\n”);
scanf(“%s”,f);
printf(“输入要计数的字符\n”);
scanf(“%c”和“&k”);
int k_int=tolower((无符号字符)k);
fp1=fopen(f,“r”);
而((c=fgetc(fp1))!=EOF)
{
if(tolower(c)=k_int){
计数++;
}
}
fclose(fp1);
printf(“文件“%s”有%d个字母%c\n”、f、count、k的实例);
返回0;
}

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

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

    tolower
    char
    参数被强制转换为
    (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;
}

提示:数据类型(或者更确切地说是“类型”)
c
k
的大小写不一样。如果你只需要使用
fgetc
一次读取一个字符,这个程序就可以编写得容易得多。你可以使用
tolower
toupper
来制作一个字符的大小写。我不知道如果你只是比较字符,为什么还要使用strmpi函数直接比较字符这绝对是过火了一次只比较一个字符通常是比较它,即
c==k
strcmpi
这绝对是区分大小写的。你甚至不需要使用
strcmpi()
:这有点误导,实际上使用的是
strcmpi()
显然是错误的。您应该使用
scanf(“%19s”,f)保护
f
,强制转换
k
以将正值传递给
tolower()
k=tolower((无符号字符)k)
,并且可能在最后一个
printf
中输出一个换行符。
tolower
的签名是
int-tolower(int)
,因此它将自动强制转换其参数。
tolower()
仅为
无符号字符类型的值和
EOF
的值定义。如果向其传递负的
char
值,则表示行为未定义。类型应为
int
,该值必须在
无符号char
保持的范围内。但是
scanf()
不应返回超出该范围的任何内容。
scanf()
将字节存储到
k
,一个
char
变量中。如果类型
char
有符号且包含负值(例如
ee
,其ISO-8859-1编码为0xe9,因此大多数默认编译器设置的值
-23
),则将
k
传递给
tolower
具有未定义的行为
k
必须强制转换为
(无符号字符)k
,以防止出现这种情况。此外,您应该将
tolower((unsigned char)k)
的返回值存储到
int
中,以避免在
if(tolower(c)==k)
中出现不同的问题,因为
(unsigned char)“é”!='在
“é”
为负值的系统上。
#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;
}
if (tolower((unsigned char)k) == tolower((unsigned char)c[0]))
    count++;`
#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;
}
#include <stdio.h>
#include <string.h>

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

    printf("Enter the file name\n");
    if (scanf("%99s", f) != 1) return 1;

    printf("Enter the character to be counted\n");
    if (scanf(" %c", k) != 1) return 1;

    fp1 = fopen(f, "r");
    if (fp1 != NULL) {
        while (fscanf(fp1, "%c", c) == 1) {
            if (strcmpi(c, k) == 0)
                count++;
        }
        fclose(fp1);

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