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.
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
).MySpiffyDocument.txt
? That's work that the computer should do.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.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:
'\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.)sscanf
, so that only the first word on each line is read.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
.