Reputation: 5207
I have a text file in this format:
#Name #Company #ID
Name1 Brand1 1234
Name2 Brand2 5678
And a struct:
struct MyStruct{
char name[TEXT_LEN];
char company[TEXT_LEN];
char ID[TEXT_LEN];
};
typedef struct MyStruct Data_t;
What I want... is to load the data from text file in appropriate variables. It should ignore first line because those are headers...
This is what I've been trying so far but without success:
int loadDataFromFile(Data_t *items, long len, char *inputFile)
{
FILE *fp;
if ((fp = fopen(inputFile, "r")))
{
for (long i = 0; i < len; i++)
{
/*fscanf(fp, "%s %s %s\n", items[i].name, items[i].company, items[i].ID);*/
//this is commented part was not working part... More about this in EDIT
fscanf(fp, "%s %s %s\n", items[i].name, items[i].company, items[i].ID);
printf("Name: %s", items[i].name); // For first item it prints:
// Name: #Name
}
}
return 0;
}
What is wrong here?
EDIT
I've replaced the code but now it reads first line as well. Is there a way to ignore header of file (first line)?
Upvotes: 0
Views: 166
Reputation: 16540
the following proposed code:
sscanf()
and now, the proposed code:
#include <stdio.h>
#include <stdlib.h>
#define TEXT_LEN 21
struct MyStruct
{
char name[TEXT_LEN];
char company[TEXT_LEN];
char ID[TEXT_LEN];
};
typedef struct MyStruct Data_t;
long loadDataFromFile( Data_t *items, long len, char *inputFile )
{
FILE *fp = fopen(inputFile, "r");
if( ! fp )
{
perror( "fopen to read file failed" );
exit( EXIT_FAILURE );
}
// read/discard first line:
char buffer[1024];
if( ! fgets( buffer, sizeof( buffer ), fp ) ) // column header line
{
perror( "fgets failed to read column headers from input file" );
exit( EXIT_FAILURE );
}
long i = 0;
while( i < len && fgets( buffer, sizeof( buffer ), fp ) )
{
if( sscanf(buffer, "%20s %20s %20s", items[i].name, items[i].company, items[i].ID) != 3 )
{
break;
}
printf("Name: %s", items[i].name);
i++;
}
return i;
}
Upvotes: 1
Reputation: 2399
Try This,
#include <stdio.h>
#define TEXT_LEN 100
typedef struct
{
char name[TEXT_LEN];
char company[TEXT_LEN];
char ID[TEXT_LEN];
}Data_t;
int loadDataFromFile(Data_t *items, long len, char *inputFile) // change len as unsigned
{
FILE *fp;
char ch;
long i;
if ( ( fp = fopen(inputFile, "r") ) )
{
while( ( ch = getc(fp) != '\n') && ch!=EOF ); //To ignore first line
printf("Reading...\n");
for (i = 0; i < len && (fscanf(fp, "%s %s %s", items[i].name, items[i].company, items[i].ID) == 3); i++)
{
printf("\n#Name: %s #Company: %s #ID: %s", items[i].name, items[i].company, items[i].ID);
}
}
else
{
printf("File Error");
return 0;
}
return i;
}
int main()
{
Data_t data[2];
int n;
if(n=loadDataFromFile(data,2,"Txt")) //2 is number of line
{
printf("\n\nReaded !\n");
for(int i=0;i<n;i++)
printf("\n#Name: %s #Company: %s #ID: %s",data[i].name,data[i].company,data[i].ID);
}
return 0;
}
Txt:
#Name #Company #ID
Name1 Brand1 1234
Name2 Brand2 5678
Output:
Reading...
#Name: Name1 #Company: Brand1 #ID: 1234
#Name: Name2 #Company: Brand2 #ID: 5678
Readed !
#Name: Name1 #Company: Brand1 #ID: 1234
#Name: Name2 #Company: Brand2 #ID: 5678
[Done] exited with code=0 in 1.227 seconds
Upvotes: 1
Reputation: 452
you coult try changin
fscanf(fp, "%s %s %s\n", items[i].name, items[i].company, items[i].ID);
to
fscanf(fp, "%s\t%s\t%s\n", items[i].name, items[i].company, items[i].ID);
and also iterating on the file lines could be done better by using something like this
while (!EOF) {/*Code*/}
Upvotes: 0