私は実際にが一緒に文字と数字を維持するために構造体を定義します。データ形式は密接に関連していることを強く示唆しています。ここにそのアイデアを例示するプログラムがあります。
scanf形式は、多少なりともとなります(できるだけ単純ですが、単純ではありません)。たとえば、RoadRunnerは答えの手紙の前にある空白をスキップするのを忘れていました。
私たちは(私が仮定すると)ただ一つの手紙を持つのに役立ちます。 %cを除くすべての標準形式が空白をスキップすることを覚えておくと便利です。 (その文の両方の部分を忘れてはならない。)
#include<stdio.h>
#define ARRLEN 10000
// Keep pairs of data together in one struct.
struct CharIntPair
{
char letter;
int number;
};
// test data. various space configurations
// char *data = " A1, B22 , C333,D4,E5 ,F6, Z12345";
void printParsedPairs(struct CharIntPair pairs[], int count)
{
printf("%d pairs:\n", count);
for(int i = 0; i<count; i++)
{
printf("Pair %6d. Letter: %-2c, number: %11d\n", i, pairs[i].letter, pairs[i].number);
}
}
int main()
{
setbuf(stdout, NULL);
setbuf(stdin, NULL);
// For the parsing results
struct CharIntPair pairs[ARRLEN];
//char dummy [80];
int parsedPairCount = 0;
for(parsedPairCount=0; parsedPairCount<ARRLEN; parsedPairCount++)
{
// The format explained>
// -- " ": skips any optional whitespace
// -- "%c": reads the next single character
// -- "%d": expects and reads a number after optional whitespace
// (the %d format, like all standard formats except %c,
// skips whitespace).
// -- " ": reads and discards optional whitespace
// -- ",": expects, reads and discards a comma.
// The position after this scanf returns with 2 will be
// before optional whitespace and the next letter-number pair.
int numRead
= scanf(" %c%d ,",
&pairs[parsedPairCount].letter,
&pairs[parsedPairCount].number);
//printf("scanf returned %d\n", numRead);
//printf("dummy was ->%s<-\n", dummy);
if(numRead < 0) // IO error or, more likely, EOF. Inspect errno to tell.
{
printf("scanf returned %d\n", numRead);
break;
}
else if(numRead == 0)
{
printf("scanf returned %d\n", numRead);
printf("Data format problem: No character? How weird is that...\n");
break;
}
else if(numRead == 1)
{
printf("scanf returned %d\n", numRead);
printf("Data format problem: No number after first non-whitespace character ->%c<- (ASCII %d).\n",
pairs[parsedPairCount].letter, (int)pairs[parsedPairCount].letter);
break;
}
// It's 2; we have parsed a pair.
else
{
printf("Parsed pair %6d. Letter: %-2c, number: %11d\n", parsedPairCount,
pairs[parsedPairCount].letter, pairs[parsedPairCount].number);
}
}
printf("parsed pair count: %d\n", parsedPairCount);
printParsedPairs(pairs, parsedPairCount);
}
私は時々改行が発生しますWindowsの8%C上のbashとminttyと私のcygwinの環境と少し苦しんでいた
(ASCII 10)がすべき前の空白を食べる空間で食べさせて、構文解析を脱線させる。 (エラーが発生した後、エラーが発生した場合、次のコンマに遭遇するまでチャートを読み込み、そこから回復しようとする)
これはCtr-Dと入力したときに起こったコンソールウィンドウのCtr-Z)にEOFを通知しようと試みます。以下のEnterキーストロークは、改行が%cに到達するようにします。もちろん、Windowsシステム上のPOSIXエミュレーションにおけるテキストI/Oは難しいです。私は、CR-NLシーケンスの翻訳のどこかでこのバグが前後することを前提としています。ssh/puttyによるLinuxシステムでは、期待通りに動作します。
はい、可能です。 –
'fscanf'を使って' getc() 'を使わないのはなぜでしょうか? – RoadRunner
@RoadRunner scanfを使うのは、少なくとも常に1文字のときです。フォーマットは単に "%c%d"になります。そしてカンマを読んでください。 T.canの答えはそれをかなりカバーしています。 –