我的问题是从一个包含100行的文件中读取,每行包含4个字段(用4个空格分隔),如下所示:
0007 0007 NOVO BANCO, SA Bancos
0008 0008 BANCO BAI EUROPA, SA Bancos
0010 0010 BANCO BPI, SA Bancos
等...
执行此操作后,我必须将其保存在链接列表中。
我有这个:
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;
}
我的问题是如何从带有空格的文件中读取。例如,在第三个字段中,它在','之后有一个空格。也是我第一次使用列表,任何人都可以给我一个良好的开端如何做到这一点?
答案 0 :(得分:1)
您可以尝试在三个或更多连续空格处标记字符串。然后,您可以使用strtol
或类似函数转换ID。
这样做的一种方法是使用strstr
搜索三个空格,然后跳过空格。
以下简短程序实现strtok
hat的变体在三个或更多空格处分割字符串。与strtok
一样,它会修改您的字符串,因此请确保传递可修改的字符数组。
#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;
}
答案 1 :(得分:1)
这使用strstr
来标记输入字符串。数据中的第一个分隔符只有3个空格,其余的是4个,所以在每种情况下我都会查找3,然后超过所有连续的空格。
#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;
}
节目输出:
7/7/NOVO BANCO, SA/Bancos
8/8/BANCO BAI EUROPA, SA/Bancos
10/10/BANCO BPI, SA/Bancos