我有两个C程序。
首先:
#include <stdio.h>
int main(int argc, char *argv[]){
float latitude;
float longitude;
char info[80];
int started = 0;
puts("data=[");
while ((scanf("%f,%f,%79[^\n]",&latitude,&longitude, info)) == 3){
if (started)
printf(",\n");
else
started = 1;
if ((latitude < -90) || (latitude > 90)){
fprintf(stderr,"Wrong latitude %f\n", latitude);
return 2;
}
if ((longitude < -180) || (longitude > 180)){
fprintf(stderr,"Wrong longitude %f\n", longitude);
return 2;
}
printf("{latitude: %f, longitude: %f, info: '%s'}", latitude, longitude, info);
}
puts("\n]");
return 0;
}
第二名:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
char line[80];
FILE *in = fopen("spooky.csv","r");
FILE *file1 = fopen("ufos.csv","w");
FILE *file2 = fopen("disappearances.csv","w");
FILE *file3 = fopen("others.csv","w");
while(fscanf(in,"%79[^\n]\n",line)==1){
if (strstr(line, "UFO"))
fprintf(file1,"%s\n",line);
else if (strstr(line, "Disappearance"))
fprintf(file2, "%s\n", line);
else
fprintf(file3,"%s\n",line);
}
fclose(file1);
fclose(file2);
fclose(file3);
return 0;
}
我不明白为什么第一个代码用指令%79[^\n]
输出我文件的所有行,第二个代码只用这个指令%79[^\n]\n
输出所有行,如果我只输出一行文本写%79[^\n]
请解释两个代码之间的差异及其中的两条说明%79[^\n]
和%79[^\n]
答案 0 :(得分:2)
它不是导致问题的格式说明符本身,而是它与其他格式说明符一起使用的方式。
如果您阅读例如this scanf
(and family) reference您会发现"%["
格式不会跳过前导空格,而大多数其他格式(例如"%f"
)都会。
当您在第一个程序中阅读输入时,您不需要scanf
函数来读取结束换行符(这是一个空白字符),因为下次调用{{1} }}将导致scanf
格式说明符在尝试读取浮点值之前跳过该换行符。
对于第二个程序,如果您有"%f"
,那么"%79[^\n]"
将会读取,但不包括第一个换行符。然后在循环的下一次迭代中,相同的格式将尝试读取字符,直到有换行符,但输入中的第一个字符是换行符,因此实际上不会读取任何内容。
如果您添加尾随换行符(任何空白字符都可用),则fscanf
函数将跳过换行符,因此下一次调用fscanf
将正确读取下一行。您可以通过在格式中使用前导空间来完成相同的操作。即而不是fscanf
你可以有
"%79[^\n]\n"
。
话虽如此,如果您想阅读行,请改用fgets
。这就是它的作用,没有" %79[^\n]"
将会遇到的许多问题。
答案 1 :(得分:1)
任何不在转换规范中的空格字符都会丢弃输入中任意数量的连续空白字符。因此,\n
会在后者中使用那些空格字符。
现在,%f
将丢弃所有前面的空白字符,直到找到非空白字符,并从该字符开始转换。 %[^\n]
不会丢弃任何字符 - 它会从输入中的第一个字符开始转换。