0

Let's assume I've got a file

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

I need to find lines with length >= 5. Here is the code

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

where sizeCap is a constant, defined as

const int sizeCap = 5;

My main() function

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

The problem is that it returns 10 instead of 8. And I don't get the idea why.

I don't have an IDE beside me so I have to use g++ and command line to compile it so I cannot debug it (or at least I don't know how).

What is the problem?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
lapots
  • 12,553
  • 32
  • 121
  • 242
  • 5
    `fgets` keeps the new-lin character at the end of the line, which contributes to the `strlen`. You can `strtok(line, "\n")` to remove it. `strtok` is in `` – M Oehm May 05 '15 at 08:34
  • 3
    Printing the lines that are longer than `sizeCap` would show you the problem. – Paul Hankin May 05 '15 at 08:40
  • Compile with all warnings and debug info (`gcc -Wall -Wextra -g`). Then **use the debugger** (`gdb`); BTW, use `g++` for C++ code and `gcc` for C code, since C and C++ are different languages. – Basile Starynkevitch May 05 '15 at 08:46

1 Answers1

3

This is because fgets() reads and stores the trailing newline \n. This \n gets counted as one element while calculating strlen().

You need to strip off that \n after taking the input.

  • Manual Way

    1. check the strlen().
    2. check the n-1the byte for \n, replace with \0.
    3. calculate the final(actual) strlen.
  • Using library function

using strchr()

  1. You need to use strchr() to find out the trailing \n.
  2. if found, replace the \n to \0 using the retuned pointer.
  3. Also, you can get the new string length by subtracting the returned pointer from the original input string.

    Sample Code:

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

using strtok()

  1. Have a look at the man page of strtok(). After reading the input, you can parse the string using \n as delimter.
  2. calculate the strlen() of the returned token, if it is not NULL.

Some suggestions:

  1. always check the return value of fopen() against NULL to ensure the success.
  2. The recommended signature of main() is int main(void).
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261