0

How can I check if a given FILE* contains a string in C running on Linux (if it matters)?

The string must consist of the whole line it's on. For example, this:

jfjfkjj
string
jfjkfjk

would be true; but this:

jffjknf
fklm...string...lflj
jfjkfnj

wouldn't. I'm essentially looking for an internal alternative to system("grep -x file")

10
  • 6
    Read line by line and compare. Commented Jun 27, 2018 at 18:03
  • 1
    You can use functions like getline and strcmp, etc. Commented Jun 27, 2018 at 18:10
  • @lurker Okay, I'll read their manpages. Commented Jun 27, 2018 at 18:11
  • while(fgets( ....) != NULL) and remember to remove any trailing newline. Commented Jun 27, 2018 at 18:14
  • @WeatherVane I just now saw your comment, that's indeed the code I came up with just now. I know this is somewhat off-topic, but what's the difference between while(fgets( ....) != NULL) and while(!fgets( ....))? Commented Jun 27, 2018 at 18:40

1 Answer 1

0

This reads a file line by line and checks if the line matches the string supplied in argument 1 (argv[1]) after every read. If so, it sets the bool infile (bools defined in <stdbool.h>) to true.

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

int main(int argc, char **argv[]) {
    char    *filepath = "/path/to/file";
    bool    infile = false;
    char    *line = NULL;
    size_t  len = 0;
    ssize_t read;

    FILE    *fp = fopen(filepath, "r");

    if (!fp) {
        fprintf(stderr, "Failed to open %s\n", filepath);
        return 1;
    }

    while ((read = getline(&line, &len, fp)) != -1) {
        line[strcspn(line, "\n")] = 0;
        if (!strcmp(line, argv[1])) {
            infile = true;
            break;
        }
    }
    fclose(uuidfp);

    if (line)
        free(line);

    return 0;
}
Sign up to request clarification or add additional context in comments.

9 Comments

If you're looking to improve performance, you might want to hash the target line and compare the hash to each line in the file first. You'll still need to do the strcmp() in case of hash collisions, but collisions should be rare, unless you expect adversarial input.
@EOF I wouldn't expect that'd be worth the trouble.
@SteveSummit I'd expect it depends. An even simpler test would be to use the return value of getline(), which must either be strlen(argv[1]) or strlen(argv[1])+1 for the strings to possibly be equal.
A reasonable solution, but has no report about whether the string from argv[1] was found in the file. And it has a flaw that you failed to check argc to ensure there is an argv[1] supplied. Moreover, the main argument is incorrect; char **argv[] should be either char *argv[] or char **argv.
@EOF 2nd idea is a good one.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.