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

标签 c scanf

我有一个坐标对的输入文件(假设有 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
}

抱歉,循环条件较长,可读性可能较差。关于如何继续的任何建议?

最佳答案

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

因此,出于您的目的,您需要一个如下格式字符串:

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 和 friend 们的事情是,他们想要读取由空格分隔的内容,并且他们真的不关心它是什么类型的空格。因此,在一行上仅使用空格(或制表符)输入所有内容与多行“相同”。这是 scanf 工作方式的一个有意的“功能”,因此,如果您确实关心换行符和其他空格之间的区别,则 scanf 不是正确的工具。

关于c - 如何在不使用 EOF 的情况下读取输入文件的下一行直到文件末尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54793002/

相关文章:

c - Scanf 和一个手动函数一起工作时获取字符串

c - 为什么我不能使用 %s 而不是 %c?

将 float 转换为 char*

c - 如何使用带有未知参数的 'print' 宏

c - 如何在 C 中为匿名结构声明全局变量?

c - 从c中的文本文件读取 float 时出现错误值

c - 在 Windows 控制台上阅读土耳其语字符

c - 读取以逗号分隔的字符串

c - 我正在为 C 中的 fgets 函数而苦苦挣扎

C宏展开固定大小的数组声明,用索引后缀重命名每个