0

So i have to write a function that reads a file (.txt) and searches for a specific string, and then make it return the whole line that the string was on.

For example, one line is composed by student number, name, date of birth, address and course. I need to search for a name, and i need it to return the whole line, containing number, name, etc.

Ex :

Input : Search for student name : HUGO

Output :

61892 HUGOABC 12-02-2001 Address123 ETD

81029 HUGOBCA 09-09-2000 Address123 EAC

Here's my code :

fp = fopen("database_Alunos.txt", "r+");

if (fp == NULL) {
    printf("Error! File is NULL...");
    system("pause");

    main();
}
else {
    char nome[50];

    printf("Choose name to search : ");
    scanf("%[^\n]s", &nome);

    /* ??? */

    fclose(fp);
    system("pause");
    main();

fp is a FILE *fp, declared on top of main();

I need to know what kind of functions I can use in the space in the code with the question marks to make it scan for 'nome' and return the whole line

Community
  • 1
  • 1
  • 3
    Calling main is rarely a good idea. What caused that decision? – Yunnosch Dec 26 '19 at 17:51
  • 1
    Please make a [mre] of your code to simply read and print the whole input file. That is the foundation for further work. – Yunnosch Dec 26 '19 at 17:52
  • Then read https://en.cppreference.com/w/c/string/byte/strchr and explain why that does not help you achieve your goal. – Yunnosch Dec 26 '19 at 17:55
  • 2
    I suggest to read the input file line-by-line (e.g. using `getline` or `fgets` - see also [this question](https://stackoverflow.com/questions/3501338/c-read-file-line-by-line)) and use `strstr`to find the substring within the line (see also [this question](https://stackoverflow.com/questions/12784766/check-substring-exists-in-a-string-in-c)). – Gerd Dec 26 '19 at 17:56
  • As it is, your question lacks focus on the actual searching problem you encountered while trying. – Yunnosch Dec 26 '19 at 17:58
  • 2
    In `scanf` the correct destination in `nome` instead of `&nome` – Roberto Caboni Dec 26 '19 at 17:58
  • all the code is inside main, so calling main will make the program start all over again, i only have about 3 months experience in C so im not really sure why its a bad ideia? – sandpaperman335 Dec 26 '19 at 18:18
  • 1
    `scanf("%[^\n]", nome);` no `"s"` in conversion, no `&` in "destination for `"%[...]"`" as `nome` already specifies the destination. – pmg Dec 26 '19 at 18:26
  • How would you do this _efficiently_ for a large amount of names and queries is a whole different and interesting problem. An index in the form of a trie? – Neil Jan 07 '20 at 17:12

2 Answers2

2

You'll need to loop through a getline using your fp, then you can use for example strstr to check if the name is present in this string. Note that you'll have to handle the case when the name is present in the address.

char *line = NULL;
size_t len = 0;
ssize_t read;

while ((read = getline(&line, &len, fp)) != -1) {
    if (strstr(line, nome) != NULL) {
        printf("%s\n", line);
    }
}
Lucas Gras
  • 961
  • 1
  • 7
  • 22
1

Ok i figured it out, this is a function to read the line

int readline(char *buff, int len, FILE *fp) {
buff[0] = '\0';
buff[len - 1] = '\0';
char *tmp;

if (fgets(buff, len, fp) == NULL) {
    *buff = '\0';
    return 0;
}
else {
    if ((tmp = strrchr(buff, '\n')) != NULL) {
        *tmp = '\0';
    }
}
return 1;

}

Func to read name and return lines :

scanf("%[^\n]s", fgets(nome, sizeof(nome), stdin));

        char line[1024];

        while (readline(line, 1024, fp)) {
            char *aux = strdup(line);

            char *numero = strtok(aux, "\t");
            char *nomeAluno = strtok(NULL, "\t");

            if (strstr(nomeAluno, nome) != NULL) {
                printf("%s\n", line);
            }
        }

    }