0

I was coding a very simple programme to detect word pattern by entering to stdin and return the times found the pattern. However the code return me the correct number but follow a char D.

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

#define MAXLINE 1000 /* maximum input line length */

char pattern[] = "ould"; /* pattern to search for */

/* print all lines from standard input that match pattern */
int main()
{
    char line[MAXLINE];
    int found = 0;

    while (fgets(line, MAXLINE, stdin) != NULL)
        if (strstr(line, pattern) != NULL) {
            printf("%s", line);
            found++;
        }
    printf("%d \n", found);
    return 0;
}

Result:

glaroam2-180-76:Lab2 apple$ ./find0
fould
fould
1D
Pablo
  • 13,271
  • 4
  • 39
  • 59
Steven T.
  • 109
  • 2
  • 8

2 Answers2

2

The code is correct (apart from the #include "string.h" which should be #include <string.h>)1, the problem is that when you press Ctrl+D on your terminal, your terminal might write something on the terminal, which you cannot control and this output might be

^D

After fgets returns NULL, you do printf("%d \n", found); which prints the '1'. But because there was ^D on the terminal, the ^ was replaced by the '1' and you end up with:

1D

Change your last printf to this:

printf("\n\n%d \n, found);

And you might see only a '1' in the next lines of the output.

This has nothing to do with your C program, it's the behaviour of your terminal. My terminal for example doesn't print when pressing Ctrl+D, but when pressing Ctrl+C I get ^C. There's nothing you can do.

edit

With There's nothing you can do I mean that you cannot control the way the terminal from you C program without calling external tools like stty. While this might solve your problem, you are loosing portability.

However, before you start you program, you can configure your terminal using a program like stty. See Jonathan Leffler's answer for more info on that.


Fotenotes

1As Jonathan Leffler points out in the comments, using quotes instead of angle brackets for system headers is not an error per se. For example my GCC compiler searches in the same directory of the compiled file for headers that were included with quotes. But in general, it's a good practice to include the header files included provided by your system with angle brackets.

Pablo
  • 13,271
  • 4
  • 39
  • 59
  • 1
    Note that `#include "string.h"` isn't precisely wrong. When the quotes are used instead of the angle brackets around a header, the compiler may search in some implementation defined extra locations for a `string.h` header before falling back on the same search as for angle brackets. It is better to use angle brackets around system-provided headers; the standard always shows them in angle brackets. But it isn't 100% wrong to use quotes. – Jonathan Leffler Feb 04 '18 at 23:47
  • Also, on Unix-like systems, you can control the appearance of control characters with `stty -echoctl` (no `^D`) or `stty echoctl` (show `^D` — usually the default). – Jonathan Leffler Feb 04 '18 at 23:49
2

It's a terminal setting: echoctl. It means that when you type Control-D, the terminal echoes ^D, and then the 1 overwrites the ^. Try using:

stty -echoctl

and then rerunning your program.

With that said, I'm surprised that the D isn't wiped out by the blank after the %d in the format string. I suspect your actual code may be missing that. When I tested on my Mac, the program with the space after the %d did not show the D for long enough for me to spot it; when I removed that space, I got the output shown in the question.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I was wandering the same, but perhaps the the `ctrl+d` outputs more than 2 chars (`^` may be representing more than one byte) which is not even printed in the terminal. – Pablo Feb 04 '18 at 23:41