I want read a txt file that has up to 10 lines. The file is formatted like this on all lines:
1 1 8
2 2 3
3 1 15
4 2 7
I'm trying to write a function that will read from only the line provided by an int passed to it. I thought of using a for loop to iterate through the lines without scanning anything but I can't figure out how to implement that.
My function so far looks like this, the for loop has not been implemented properly yet.
void process(int lineNum, char *fullName)
{
int ii, num1, num2, num3;
FILE* f;
f = fopen(fullName, "r");
if(f==NULL)
{
printf("Error: could not open %S", fullName);
}
else
{
for (ii=0 (ii = 0; ii < (lineNum-1); ii++)
{
/*move through lines without scanning*/
fscanf(f, "%d %d %d", &num1, &num2, &num3);
}
printf("Numbers are: %d %d %d \n",num1, num2, num3);
}
}
You were nearly done but you simply need to change the format specifier.The following code reads through the lines preceding your intended line,but ignores what it reads.
for (ii=0 (ii = 1; ii < (lineNum-1); ii++)
{
/*move through lines without scanning*/
fscanf(f, "%*d %*d %*d%*c");
// fscanf(f, "%*d %*d %*d\n");
}
fscanf(f,"%d%d%d",&num1,&num2,&num3);
You will have to read all the lines up to the one you want.
I'd probably use fgets()
to read the lines and sscanf()
to parse the required line. However, you can add a loop to read the unwanted lines (still fgets()
) and then read the line you want with fscanf()
. Do check that you got three values: you must check the return value from fscanf()
. Also remember to close the file you opened.
void process(int lineNum, char *fullName)
{
FILE *f = fopen(fullName, "r");
if (f == NULL)
{
fprintf(stderr, "Error: could not open %S", fullName);
return;
}
int num1, num2, num3;
for (int i = 0; i < lineNum; i++)
{
if (fscanf(f, "%d %d %d", &num1, &num2, &num3) != 3)
{
fprintf(stderr, "Format error on line %d\n", i+1);
fclose(f);
return;
}
}
printf("Numbers are: %d %d %d \n",num1, num2, num3);
fclose(f);
}
Note that this code does not actually enforce lines separating the sets of numbers (one of the disadvantages of the file-based members of the scanf()
family of functions. For that, you need fgets()
and sscanf()
:
void process(int lineNum, char *fullName)
{
FILE *f = fopen(fullName, "r");
if (f == NULL)
{
fprintf(stderr, "Error: could not open %S", fullName);
return;
}
char line[4096];
for (i = 0; i < lineNum; i++)
{
if (fgets(line, sizeof(line), f) == 0)
{
fprintf(stderr, "Premature EOF at line %d\n", i+1);
fclose(f);
return;
}
// Optionally check format here...
}
int num1, num2, num3;
if (sscanf(line, "%d %d %d", &num1, &num2, &num3) != 3)
{
fprintf(stderr, "Format error on line %d\n", i+1);
fclose(f);
return;
}
printf("Numbers are: %d %d %d \n",num1, num2, num3);
fclose(f);
}
you need to use checks for your input scans. you might potentially run into errors or EOF.
if(line < 1) //check for invalid line number
{
printf("Invalid line number..aborting\n");
exit(1); //aborting is optional
}
for(int i = 0;i<line-1;i++)
{
switch(flag = fscanf(fp,"%*d %*d %*d"))//flag is for debug only
{
case 0 ://since we are ignoring the read, fscanf return 0
case 3:break; //normal read (should not happen)
default:printf("File read Error\n");//if fscanf returns EOF, 1,2
}
}
if(EOF ==fscanf(fp,"%d%d%d",&n1,&n2,&n3))//check for EOF. last scan might have ignored till last line
{
printf("File read Error: end of file reached");
}
else
{
printf("\n%d, %d, %d",n1,n2,n3);//normal case
}