0

I have a txt file with some file names and their size. This is how I wrote the txt file:

banana //file name
3 //the size of file banana
programs
12
music
524

I have to find a keyboard entered file name and display it's size.

This is my code:

 FILE *text;
 text=fopen("text.txt","r");
 printf("Scan the number of letters of your file name");
 int n;
 scanf("%d",&n);
 char s[++n];
 printf("Scan the file name you are looking for: ");
 int i;
   for(i=0;i<=n;i++)
   {
       scanf("%c",&s[i]);
   }
 int l=0;
 char c[n];
 char g;
   while(!feof(text))
   {
       if(l%2==1) {fgetc(text); fgetc(text); l++;}
       if(l%2==0)
       {
         fgets(c,n,text);
         fgetc(text);
           for(i=0;i<n;i++)
           {
             printf("%c",c[i]);
           }
           l++;
       }
   }

Obviously, it's not correct. Can you help me? I'm a little bit confuse.

mico
  • 12,730
  • 12
  • 59
  • 99
  • 2
    First observation: `feof` is not the way to do it [Why is “while ( !feof (file) )” always wrong?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong). The way to go is a loop controlled by the result of `fgets` which reads one text line at a time. `while (fgets(...) != NULL) {}` then you analyse the string that was read. – Weather Vane Jan 02 '16 at 19:44
  • `for(i=0;i<=n;i++) { scanf("%c",&s[i]); }` <--- You're overflowing this buffer. Stop. Which book are you reading? Whatever it is, it's not working for you... Would you like a suggestion for a book that typically works much better? – autistic Jan 02 '16 at 20:01

1 Answers1

1

Ugh! Please learn more about basic input. Your program has various flaws:

  • fgetc reads single characters. This can be useful at times, but obviously you want to read whole lines. fgets does this. You use it once, but it is not advisable to mix these. Decide up front which input paradigm you want to use: char-wise (fgetc), line-wise (fgets) or token-wise (fscanf).
  • Please don't make the user enter the number of characters in the filename. Quick, how many characters are there in MySpiffyDocument.txt? That's work that the computer should do.
  • Don't use feof to control yopur input. All input functions have special return values toat indicate that either the end of the file was read or that an error occurred. For fgets, this return value is NULL, for fgetc, this return value is the special constant EOF. The functions feof and ferror are useful after you have encountered the special return values for a post mortem analysis of the two end conditions.
  • Your inner loop, which is responsible for the core program logic, doesn't make sense at all. For example, for an odd l, increment l and then test for an even l – which will be true, because you have just incrremented an odd l. Use else in such cases. And don't place things that happen anyway in conditional blocks: Increment l once after the if/else blocks.

Here's an example implementation:

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

int process(const char *filename)
{
    char line[80];
    char name[80];
    int size;
    int count = 0;

    FILE *f = fopen(filename, "r");

    if (f == NULL) return -1;

    while (fgets(line, sizeof(line), f)) {
        if (count % 2 == 0) {
            if (sscanf(line, "%s", name) < 1) continue;
        } else {
            if (sscanf(line, "%d", &size) < 1) continue;
            printf("%12d   %s\n", size, name);
        }

        count++;
    }
    fclose(f);

    return 0;    
}

int main()
{
    char line[80];
    char name[80];

    puts("Please enter filename:");

    while (fgets(line, sizeof(line), stdin)) {
        if (sscanf(line, "%s", name) == 1) {
            process(name);
            break;
        }
    }

    return 0;
}

Things to note:

  • The program uses 80 characters a max. buffer size; that means your lines can be up to 78 characters long – line content plus new-line '\n' plus null terminator '\0'. That should be okay for many cases, but eventually the line may overflow. (So your file-name letter count has some merit, but the real solution here is to allocate memory dynamically. I won't open that can of worms now.)
  • The code uses a double strategy: Read lines first, then scan into these lines with sscanf, so that only the first word on each line is read.
  • Empty lines are skipped. Even lines that don't hold a valid number are skipped, too. This is sloppy error handling and may trip the odd/even count.
  • Reading stuff interactively from the keyboard isn't very easy in C. The awkward fgets/sscanf construct in main tries to handle the case when the user enters an empty line or evokes an end-of-file signal via Ctrl-D/Z. A better and easier way is to provide arguments to the command line via argc and argv.
  • I've moved the file reading into a separate function.
M Oehm
  • 28,726
  • 3
  • 31
  • 42