我有一个坐标对的输入文件(可以说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
}
很抱歉出现长循环条件,并可能会降低可读性。有关如何进行的任何建议?
答案 0 :(得分:1)
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和朋友的事情是,他们想阅读由空格分隔的内容,而他们实际上并不关心它是哪种空格。因此,在一行中仅输入空格(或制表符)的所有内容都与多行“相同”。这是scanf工作方式的故意“功能”,因此,如果您实际上关心换行符和其他空格之间的差异,则scanf不是正确的工具。
答案 1 :(得分:0)
$xml->encoding = 'UTF-8';
return $xml->save('php://output');
答案 2 :(得分:-1)
更好的设计是使用直接的字符串读取功能(例如fgets
)从文件中读取行,然后对通过sscanf
或类似文件从文件读取的字符串进行字符串解析。 scanf
-系列功能通常不应直接从流中读取,而只能从字符串中读取。
然后,您还应该检查sscanf
的返回值,以确保将每个值都适当地扫描到了预期的类型中。
char line[200];
while(fgets(line, 200, stdin))
{
if(sscanf(line, "<format-string-here>", ...) != 16)
{
// handle error
}
}