Reputation: 119
My problem is to read from a file with 100 lines, each line with 4 fields(separated by 4 spaces), which looks like this:
0007 0007 NOVO BANCO, SA Bancos
0008 0008 BANCO BAI EUROPA, SA Bancos
0010 0010 BANCO BPI, SA Bancos
etc...
After doing this i have to save it in a linked list.
Atm i have this:
struct list{
int code1;
int code2;
char name[100];
char type[100];
struct list *next, *current;
};
int main()
{
FILE *fp1;
struct list iban;
fp1 = fopen("ibanlist.txt", "r");
if(fopen == NULL)
{
printf("Error!");
}
fscanf(fp1, /*what should i do here?*/, iban.code1, iban.code2, iban.name, iban.type);
//should i use fgets and sscanf instead?
fclose(fp1);
return 0;
}
My problem is how to read from the file with the spaces. For example in the third field it has a space after the ','. Also its the first time im using lists, can anyone give me a head start how to do it?
Upvotes: 0
Views: 71
Reputation: 34575
This uses strstr
to tokenise the input string. The first delimiter in the data is only 3 spaces, the rest are 4, so in each case I look for 3 and then advance past all consecutive spaces.
#include <stdio.h>
#include <string.h>
struct list{
int code1;
int code2;
char name[100];
char type[100];
};
int main(void)
{
FILE *fp;
char str [1000];
char *aptr, *bptr, *cptr;
struct list rec;
if ((fp = fopen("file.txt", "rt")) == NULL)
return 1;
while(fgets(str, sizeof str, fp) != NULL) {
// break the input line
aptr = strstr(str, " "); // isolate first field
if(aptr == NULL)
return 1;
*aptr++ = '\0';
while (*aptr == ' ')
aptr++;
bptr = strstr(aptr, " "); // isolate second field
if(bptr == NULL)
return 1;
*bptr++ = '\0';
while (*bptr == ' ')
bptr++;
cptr = strstr(bptr, " "); // isolate third field
if(cptr == NULL)
return 1;
*cptr++ = '\0';
while (*cptr == ' ')
cptr++;
cptr [ strcspn(cptr, "\r\n") ] = 0; // remove trailing newline etc
// extract the data
if(sscanf(str, "%d", &rec.code1) != 1)
return 1;
if(sscanf(aptr, "%d", &rec.code2) != 1)
return 1;
strcpy(rec.name, bptr);
strcpy(rec.type, cptr);
// print the result
printf("%d/%d/%s/%s\n", rec.code1, rec.code2, rec.name, rec.type);
}
fclose(fp);
return 0;
}
Program output:
7/7/NOVO BANCO, SA/Bancos
8/8/BANCO BAI EUROPA, SA/Bancos
10/10/BANCO BPI, SA/Bancos
Upvotes: 1
Reputation: 29126
You could try to tokenise the string at, say, three or more consecutive spaces. You would then convert the ids with strtol
or similar functions.
One way to do so is to search for three spaces with strstr
and then skip spaces after that.
The following short program implements a variant of strtok
hat splits a string at three or more spaces. Like strtok
, it modifies your string, so make sure that you pass a modifiable char array.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char *token(char *str)
{
static char *p;
char *res;
if (str) p = str;
if (p == NULL) return p;
while (*p == ' ') p++;
if (*p == '\0') return NULL;
res = p;
p = strstr(p, " ");
if (p && *p) {
*p = '\0';
p++;
}
return res;
}
int main()
{
char str[] = "0008 0008 BANCO BAI EUROPA, SA Bancos";
char *t;
t = token(str);
while (t) {
puts(t);
t = token(NULL);
}
return 0;
}
Upvotes: 1