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