【问题标题】:find number of lines with length more than 5查找长度超过 5 的行数
【发布时间】:2015-05-05 08:32:11
【问题描述】:

假设我有一个文件

a
ab
abc
abcd
abcde
abcdef
abcdefg
abcdefgh
abcdefgh
abcdefg
abcdef
abcde
abcd
abc
ab
a

我需要找到带有length >= 5 的行。 这是代码

int cOriginal(char *fileName)
{
    FILE *file = fopen(fileName, "r");
    char line[256];
    int numberOfStrings = 0;
    while(fgets(line, sizeof(line), file))
    {
        if (strlen(line) >= sizeCap)
        {
            numberOfStrings++;
        }
    }
    fclose(file);
    return numberOfStrings;
}

其中sizeCap是一个常数,定义为

const int sizeCap = 5;

我的main() 函数

int main()
{
    char filename[] = "file.txt";
    int cnt3 = cOriginal(filename); // th
    printf("Using function3: %d", cnt3);
    return 0;
}

问题是它返回10 而不是8。我不明白为什么。

我身边没有 IDE,所以我必须使用 g++ 和命令行来编译它,所以我无法调试它(或者至少我不知道如何调试)。

有什么问题?

【问题讨论】:

  • fgets 将 new-lin 字符保留在行尾,这有助于 strlen。您可以strtok(line, "\n") 删除它。 strtok<string.h>
  • 打印比sizeCap长的行会显示问题。
  • 编译时包含所有警告和调试信息 (gcc -Wall -Wextra -g)。然后使用调试器 (gdb);顺便说一句,C++ 代码使用g++,C 代码使用gcc,因为C 和C++ 是不同的语言。

标签: c string fgets


【解决方案1】:

这是因为fgets() 读取并存储了尾随换行符\n。这个\n 在计算strlen() 时被计为一个元素

您需要在输入后去掉 \n

  • 手动方式

    1. 检查strlen()
    2. 检查n-1字节中的\n,替换为\0
    3. 计算最终(实际)strlen
  • 使用库函数

使用strchr()

  1. 您需要使用strchr() 查找尾随\n
  2. 如果找到,请使用重新调整的指针将 \n 替换为 \0
  3. 另外,您可以通过从原始输入字符串中减去返回的指针来获得新的字符串长度。

    示例代码:

    int length = 0;
    char*nl=strchr(line,'\n'); 
    if (nl) 
    {
        *nl='\0';
        length =  nl - line;
    }
    else
        length = strlen(line);
    

使用strtok()

  1. 看看man pagestrtok()。读取输入后,您可以解析使用\n作为分隔符的字符串。
  2. 如果不为NULL,则计算返回令牌的strlen()

一些建议:

  1. 始终检查 fopen() 的返回值与 NULL 是否相符,以确保成功。
  2. main() 的推荐签名是int main(void)

【讨论】:

  • 为什么要这么做?我的意思是在行尾添加\n
  • @user1432980 这就是fgets() 的行为方式。查看我提供的链接了解更多详情。
  • 对于查找\nstrchrstrtok 更好而且更快;并且不需要计算strlen 两次。
  • @BasileStarynkevitch 先生,1) 对于 finding \n strchr() 的存在当然更好,但是在这里,我们需要去掉 \n,即,我们需要一个没有\n字符串,那么在这种情况下,strtok() 不是更好的选择吗? 2)你是对的,那是一个错字。删除了双strlen() 检查..
  • 不,只需编码char*nl=strchr(line,'\n'); if (nl) *nl='\0';(你甚至可以避免在找到\n 时调用strlen,在这种情况下使用nl-line
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-03
相关资源
最近更新 更多