1

私は本、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 に変更してみました。どちらも違いはありませんでした。データを入力したとき、この奇妙なことは起こりませんでした。

どのように見えるべきか:

本からの書式付きデータ

実際にどのように見えるか。最後の行がどのように異なるかに注意してください。ところで、緯度の「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を試してみましたが、どちらも同じ結果でした。

どんな助けや洞察もいただければ幸いです!

4

2 に答える 2

3

あなたのファイルには Windows スタイルのCRLF 行末が含まれており、あなたのプログラムはそれらを処理する準備ができていません。この本の著者は、Windows スタイルのテキスト ファイルでテストせずに、Linux または Mac マシン (LF 改行) を想定しています。その結果、各行のキャリッジ リターン (CR) 文字が stringinfoに含まれたままになり、出力が台無しになります。

CR と LF の両方の文字をスキャンするようにプログラムを変更するには、次のようにします。

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

に注意してください\r

(Linuxで試したとのことですが、Windowsで作った入力CSVファイルを使ったのでしょうか?)

于 2013-08-22T11:32:57.520 に答える
1

変更してみる

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

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

入力ファイルにリターンが含まれている可能性があると思います (Windows ボックスからでしたか?)。

于 2013-08-22T11:34:57.680 に答える