从文本文件扫描数据,每个数据项之间没有间距 [英] Scanning data from text file, that doesn't have spacing between each item of data

查看:44
本文介绍了从文本文件扫描数据,每个数据项之间没有间距的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的作业遇到了问题.我需要将文本文件中的一些数据扫描到结构中.文本文件看起来像这样.

I have encountered a problem with my homework. I need to scan some data from a text file, to a struct. The text file looks like this.

012345678;danny;cohen;22;M;danny1993;123;1,2,4,8;Nice person
223325222;or;dan;25;M;ordan10;1234;3,5,6,7;Singer and dancer
203484758;shani;israel;25;F;shaninush;12345;4,5,6,7;Happy and cool girl
349950234;nadav;cohen;50;M;nd50;nadav;3,6,7,8;Engineer very smart
345656974;oshrit;hasson;30;F;osh321;111;3,4,5,7;Layer and a painter 

每个数据项与其匹配的变量.id = 012345678名字 = 丹尼等等...

Each item of data to its matching variable. id = 012345678 first_name = danny etc...

现在我不能使用 fscanf,因为没有间距,并且 fgets 扫描所有行.

Now I can't use fscanf because there is no spacing, and the fgets scanning all the line.

我用 %[^;]s 找到了一些解决方案,但是我需要编写一个代码块,然后为每一项数据复制并传递 9 次.

I found some solution with %[^;]s, but then I will need to write one block of code and, copy and past it 9 times for each item of data.

如果每个数据项之间有间距,是否还有其他选项而不更改文本文件,类似于我用 fscanf 编写的代码?

Is there any other option without changing the text file, that similar to the code I would write with fscanf, if there was spacing between each item of data?

**************** 更新 **************

************* UPDATE **************

嘿,首先,感谢大家的帮助,真的很感激.我不明白你所有的答案,但我确实使用了一些东西.

Hey, First of all, thanks everyone for the help really appreciating. I didn't understand all your answers, but here something I did use.

这是我的代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    char *idP, *firstNameP, *lastNameP;
    int age;
    char gender, *userNameP, *passwordP, hobbies, *descriptionP;
}user;


void main() {
    FILE *fileP;
    user temp;
    char test[99];

    temp.idP = (char *)malloc(99);
    temp.firstNameP = (char *)malloc(99);
    temp.lastNameP = (char *)malloc(99);
    temp.age = (int )malloc(4);
    temp.gender = (char )malloc(sizeof(char));
    temp.userNameP = (char *)malloc(99);

    fileP = fopen("input.txt", "r");
    fscanf(fileP, "%9[^;];%99[^;];%99[^;];%d;%c", temp.idP,temp.firstNameP,temp.lastNameP,&temp.age, temp.gender);
    printf("%s\n%s\n%s\n%d\n%c", temp.idP, temp.firstNameP, temp.lastNameP, temp.age, temp.gender);

    fgets(test, 60, fileP); // Just testing where it stop scanning
    printf("\n\n%s", test);

    fclose(fileP);
    getchar();
}

一切正常,直到我扫描 int 变量,之后它没有扫描任何东西,我得到一个错误.

It all works well until I scan the int variable, right after that it doesn't scan anything, and I get an error.

非常感谢.

推荐答案

正如评论中所讨论的,fscanf 可能是最短的选项(尽管 fgets 后跟 strtok 和手动解析是可行的选择).

As discussed in the comments, fscanf is probably the shortest option (although fgets followed by strtok, and manual parsing are viable options).

您需要对字符串字段使用 %[^;] 说明符(意思是:一串字符 other than ;), 用 ; 分隔字段以使用实际的分号(我们特别要求不要将其作为字符串字段的一部分使用).最后一个字段应该是 %[^\n] 以消耗到换行符,因为输入没有终止分号.

You need to use the %[^;] specifier for the string fields (meaning: a string of characters other than ;), with the fields separated by ; to consume the actual semicolons (which we specifically requested not to be consumed as part of the string field). The last field should be %[^\n] to consume up to the newline, since the input doesn't have a terminating semicolon.

您还应该(始终)将使用 scanf 系列函数读取的每个字符串字段的长度限制为比可用空间少 1(终止 NUL 字节是 +1).因此,例如,如果第一个字段的长度最多为 9 个字符,则需要 char field1[10],格式为 %9[^;].

You should also (always) limit the length of each string field read with a scanf family function to one less than the available space (the terminating NUL byte is the +1). So, for example, if the first field is at most 9 characters long, you would need char field1[10] and the format would be %9[^;].

在格式字符串的开头放置一个空格以消耗任何空格(例如前一个换行符)通常是个好主意.

It is usually a good idea to put a single space in the beginning of the format string to consume any whitespace (such as the previous newline).

而且,当然你应该检查fscanf的返回值,例如,如果你按照示例有9个字段,它应该返回9.

And, of course you should check the return value of fscanf, e.g., if you have 9 fields as per the example, it should return 9.

因此,最终结果将类似于:

So, the end result would be something like:

if (fscanf(file, " %9[^;];%99[^;];%99[^;];%d;%c;%99[^;];%d;%99[^;];%99[^\n]",
           s.field1, s.field2, s.field3, &s.field4, …, s.field9) != 9) {
    // error
    break;
}

(或者,用逗号分隔的数字字段可以读作四个单独的字段,如 %d,%d,%d,%d,在这种情况下,计数将达到 12.)

(Alternatively, the field with numbers separated by commas could be read as four separate fields as %d,%d,%d,%d, in which case the count would go up to 12.)

这篇关于从文本文件扫描数据,每个数据项之间没有间距的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆