-1

I want to write a code to extract todo task list from a code file.It's basically scanning a code file and detecting lines that include "TODO" string and then writing those lines into a text file.

So far my my code is like this:

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

int main()
{
    FILE* f;
    char line[200];
     f = fopen("someFile.c", "r");
     char c;
     char str;
     while(!feof(f)){
        fgets(line,sizeof(line),f);
        if(strstr(line, "TODO") != NULL)//Extracts every line with TODO
        {
            c=fgetc(f);//c = lines with TODO
        }

         }
     fclose(f);

     f= fopen("todoListFile.txt","w");

     while(!feof(f))
     {
         fputs(c,f);//Writing the content of the c in to the text file.
     }
    fclose(f);

    return 0;
}

When I run this code it crashes after 1-2 seconds. My mistake is probably at the second part which is getting those "TODO" lines and writing down those to the text lines. But I'm pretty stuck at that part and don't know what to do.

Note: Content of someFile.c is basically some comment lines with "// TODO :"

  • Oh and a side note: Please specify why are you downvoting my question ? Im new and i dont know the all of the rules. I tried to read and pay attention to rules. –  May 13 '17 at 23:32
  • 2
    I'm wondering what do you expect from this line `c=fgetc(f);` to do? PS: People are downvoting without any good reason, you should get used to it :) – Ervin Szilagyi May 13 '17 at 23:41
  • @ErvinSzilagyi tried to add every line with TODO into the c variable then put that variable into the text file. –  May 13 '17 at 23:43
  • `c` is a single character, it will contain a single letter in the best case. – Ervin Szilagyi May 13 '17 at 23:44
  • @Ervin Szilagyi how can i fix that part do you have any idea ? –  May 13 '17 at 23:52
  • `fgets` reads the whole line from a file, so for example if your comment is `//TODO: do somehting`, then all of this text will be held in your `line` variable. Assuming that your TODO comment is not spread across multiple lines, a solution would be to extract the text after the `TODO:` keyword from `line` variable. Furthermore, if you want to store all of this text, you will have to create an array of strings. – Ervin Szilagyi May 14 '17 at 00:01
  • 3
    Note that [`while (!feof(file))` is always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong). – Jonathan Leffler May 14 '17 at 00:54
  • 3
    The code `while(!feof(f)) { fputs(c,f); }` is a quasi-infinite loop because the output won't fail until you've created a file that's too big to fit (either because you've hit a 2 GiB limit or because you've run out of disk space, and probably used far more than 2 GiB). – Jonathan Leffler May 14 '17 at 00:56
  • Welcome to StackOverflow. Some people vote down for the single reason that you did not take the [tour]. I am not saying that is good practice, but it might answer your comment on downvoting. – Yunnosch May 14 '17 at 06:05
  • @JonathanLeffler what is the right way of doing it ? –  May 14 '17 at 07:25

1 Answers1

0

The specification pretty much indicates that you have to open two files, one for reading, one for writing. As you read a line from the input file, if that line contains TODO, you need to write that line to the output file. That leads to the straight-forward code:

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

int main(void)
{
    char file1[] = "someFile.c";
    char file2[] = "todoListFile.txt";
    FILE *fp1 = fopen(file1, "r");
    if (fp1 == NULL)
    {
        fprintf(stderr, "Failed to open file %s for reading\n", file1);
        return 1;
    }
    FILE *fp2 = fopen(file2, "w");
    if (fp2 == NULL)
    {
        fprintf(stderr, "Failed to open file %s for writing\n", file2);
        return 1;
    }
    char line[200];
    while (fgets(line, sizeof(line), fp1) != 0)
    {
        if (strstr(line, "TODO") != NULL)
            fputs(line, fp2);
    }
    fclose(fp1);
    fclose(fp2);

    return 0;
}

Note that it checks that the files were opened successfully, and reports the file name if it failed, and exits with a non-zero status (you could add <stdlib.h> and use EXIT_FAILURE if you prefer).

When run on (a copy of) its own source, it leaves the todoListFile.txt containing one line:

        if (strstr(line, "TODO") != NULL)

Simple modifications of the program would:

  • Write to standard output instead a fixed name file.
  • Take command line arguments and process all the input files named.
  • Read standard input if no input files are named.
  • Increase the line length. 200 is better than 80, but lines can be longer than that. I tend to use 4096 as a line length unless there's a reason to allow longer lines.
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Thank you! I thought about doing it like this since its much easier but i remember reading somewhere that opening another file without closing previous one is strictly not recommended since it may cause bugs. But this one is workig. Thanks! Chosen as answer. –  May 14 '17 at 09:32
  • Btw `while (fgets(line, sizeof(line), fp1) != 0)` is '0' on this line means EOF ? –  May 14 '17 at 09:37
  • Since `fgets()` returns a `char *` value, it uses `0` or `NULL` to indicate EOF. – Jonathan Leffler May 14 '17 at 15:08
  • Having two or more files open isn't necessarily wrong or bad. After all, you have three open files anyway: standard input, output, error. Not closing files when they're no longer needed is a potential problem. But simply having two files open at the same time is not. – Jonathan Leffler May 14 '17 at 15:11