如何在不使用EOF的情况下读取输入文件的下一行直到文件结尾

问题描述 投票:-1回答:3

我有一个坐标对的输入文件(比方说10行),每行看起来像这样:

(1653408W,503223N)(1651614W,502806N)

我试图将给定的输入放入DMS格式。输入文件中的每一行以\n字符结尾,我想循环遍历文件并在最终的\n之后停止。我在考虑使用类似的东西:

while(fscanf(filename,
             "(%3d%2d%2d%c, %2d%2d%2d%c) (%3d%2d%2d%c, %2d%2d%2d%c)\n",
             &firstLonD, &firstLonM, &firstLonS, &firstLonC,
             &firstLatD, &firstLatM, &firstLatS, &firstLatC,
             &secLonD, &secLonM. &secLonS, &secLonC,
             &secLatD, &secLatM, &secLatS, &secLatC) == 16) {
//do something
}

很抱歉长循环条件和可能的可读性差。有关如何进行的任何建议?

c scanf
3个回答
1
投票

fscanf格式字符串中的空格和换行符与输入中的空格和换行符不匹配。相反,格式中的任何空格字符意味着“跳过空格”,读取和丢弃空格,直到找到任何非空白字符 - 这可能是下一个字符,因此不会跳过任何内容。此外,大多数转换说明符也会跳过空格,因此您只需要格式字符或%c%[%ndirectives之前格式的空格,这些空格不会跳过空格。

因此,为了您的目的,您需要一个格式字符串,如:

while(fscanf(filename,
         " (%3d%2d%2d%c ,%2d%2d%2d%c ) (%3d%2d%2d%c ,%2d%2d%2d%c )",
         &firstLonD, &firstLonM, &firstLonS, &firstLonC,
         &firstLatD, &firstLatM, &firstLatS, &firstLatC,
         &secLonD, &secLonM. &secLonS, &secLonC,
         &secLatD, &secLatM, &secLatS, &secLatC) == 16) {

虽然在循环中读取单个坐标也可能更好,但稍后将它们配对:

while(fscanf(filename,
         " (%3d%2d%2d%c ,%2d%2d%2d%c )",
         &LonD, &LonM, &LonS, &LonC,
         &LatD, &LatM, &LatS, &LatC) == 8) {

将纬度/经度读作单个数字然后将div / mod分为100度的度/分/秒也可能更好:

while(fscanf(file, " (%d%c ,%d%c )", &lonVal, &lonDir, &latVal, &latDir) == 4) {
    lonDeg = lonVal / 10000;
    lonMin = (lonVal % 10000) / 100;
    lonSec = lonVal % 100;

通过这种方式,你可以处理<100度的经度而不需要领先0来使它们正好是7位数......


关于scanf和朋友的事情是他们想要阅读由空格分隔的内容,他们真的不在乎它是什么样的空白。因此,只用空格(或制表符)输入所有一行就像多行一样“相同”。这是scanf工作方式的有意“特征”,因此如果您真正关心换行符和其他空格之间的区别,则scanf不是正确的工具。


0
投票
#include <stdlib.h>
File *file;
size_t len = 0;
ssize_t read;
char * line = NULL;     
while ((read = getline(&line, &len, file)) != -1)
{
    printf("%s",line);
    if(sscanf(line, "....format",...)==16)){
           ..............
     }
}

-1
投票

更好的设计是从具有直接字符串读取功能的文件(如fgets)中读取行,然后对使用sscanf或类似文件从文件读取的字符串使用字符串解析。 scanf-family函数通常不应该用于直接从流中读取,只能从字符串中读取。

然后,您还应检查sscanf的返回值,以确保每个值都被适当地扫描到预期类型。

char line[200];
while(fgets(line, 200, stdin))
{
    if(sscanf(line, "<format-string-here>", ...) != 16)
    {
        // handle error
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.