代码之家  ›  专栏  ›  技术社区  ›  punstress

Head First C中代码后面的奇数结果

  •  1
  • punstress  · 技术社区  · 11 年前

    我正在做一本书中的练习, Head First C 。我仔细检查了我的代码是否与书中的代码相同,并且我正在仔细遵循书中的步骤。

    C文件应该采用gps数据,并将其格式化为JSON样式。

    #include <stdio.h>
    
    int main() {
    
        float latitude;
        float longitude;
        char info[40];
        int started = 0;
    
        puts("data=[");
        while (scanf("%f, %f, %39[^\n]", &latitude, &longitude, info) ==3) {
          if (started) 
            printf(", \n");
    
          else 
            started = 1;
    
              printf("{latitude: %f, longitude: %f, info: '%s'}", latitude, longitude, info);
        }
        puts("\n]");
        return 0;
    }
    

    首先,这本书让我们输入数据,向我们展示它看起来多么乏味和格式糟糕,然后我们学会重定向stdin以读取逗号分隔的数据文件,如下所示:

    $ ./geo2json < gpsdata.csv
    

    我在网上找不到源文件,所以我从书的pdf中复制/粘贴以创建csv文件。

    gpsdata.csv and gpsdata.txt
    
    42.363400,-71.098465,Speed = 21 
    42.363327,-71.097588,Speed = 23
    42.363255,-71.096710,Speed = 17
    42.363182,-71.095833,Speed = 22
    42.363110,-71.094955,Speed = 14
    42.363037,-71.094078,Speed = 16
    42.362965,-71.093201,Speed = 18
    42.362892,-71.092323,Speed = 22
    42.362820,-71.091446,Speed = 17
    42.362747,-71.090569,Speed = 23
    42.362675,-71.089691,Speed = 14
    42.362602,-71.088814,Speed = 19
    42.362530,-71.087936,Speed = 16
    42.362457,-71.087059,Speed = 16
    42.362385,-71.086182,Speed = 21
    

    奇怪的事情发生了,所以我浏览了这些行并删除了,然后重新输入了换行符,以防有一些隐藏的格式。我试着将文件类型从.csv更改为.txt。两者都没有区别。当我输入数据时,这种奇怪的事情并没有发生。

    它应该是什么样子:

    formatted data from the book

    它的实际外观。注意最后一行的不同。顺便说一句,有时纬度上的“l”会出现在最后一行。

    login:~/programming/cfiles> ./geo2json < gpsdata.csv
    data=[
    '}, itude: 42.363400, longitude: -71.098465, info: 'Speed = 21
    '}, itude: 42.363327, longitude: -71.097588, info: 'Speed = 23
    '}, itude: 42.363255, longitude: -71.096710, info: 'Speed = 17
    '}, itude: 42.363182, longitude: -71.095833, info: 'Speed = 22
    '}, itude: 42.363110, longitude: -71.094955, info: 'Speed = 14
    '}, itude: 42.363037, longitude: -71.094078, info: 'Speed = 16
    '}, itude: 42.362965, longitude: -71.093201, info: 'Speed = 18
    '}, itude: 42.362892, longitude: -71.092323, info: 'Speed = 22
    '}, itude: 42.362820, longitude: -71.091446, info: 'Speed = 17
    '}, itude: 42.362747, longitude: -71.090569, info: 'Speed = 23
    '}, itude: 42.362675, longitude: -71.089691, info: 'Speed = 14
    '}, itude: 42.362602, longitude: -71.088814, info: 'Speed = 19
    '}, itude: 42.362530, longitude: -71.087936, info: 'Speed = 16
    '}, itude: 42.362457, longitude: -71.087059, info: 'Speed = 16
    '}atitude: 42.362385, longitude: -71.086182, info: 'Speed = 21
    ]
    

    我查看了网上的勘误表,没有看到任何关于这件事的信息。我当时使用的是Cygwin,但后来尝试了linux,两者都有相同的结果。

    如有任何帮助或见解,我们将不胜感激!

    2 回复  |  直到 11 年前
        1
  •  3
  •   Fred Foo    11 年前

    您的文件包含Windows样式 CRLF line endings 而你的程序没有能力处理它们。这本书的作者假设了一台Linux或Mac机器(LF换行符),而没有在Windows风格的文本文件上进行测试。结果是每一行的回车(CR)字符仍然包含在字符串中 info ,这会使输出出现问题。

    您可以通过以下方式修改程序以扫描CR和LF字符

    scanf("%f, %f, %39[^\r\n]", &latitude, &longitude, info)
    

    注意 \r .

    (你说你在Linux上尝试过,但我猜你使用了在Windows上制作的输入CSV文件?)

        2
  •  1
  •   noz    11 年前

    尝试更改

    while (scanf("%f, %f, %39[^\n]", &latitude, &longitude, info) ==3) {
    

    while (scanf("%f, %f, %39[^\n\r]", &latitude, &longitude, info) ==3) {
    

    我认为您的输入文件中可能有返回(它是从Windows框中返回的吗?)。