形式が常に 1 行に 1 つの数値である場合は、次を使用できます。
fscanf(fpin, "%d%*[^\n]", &var);
は%*[^\n]
、改行文字までのすべての文字を飲み込みます。は*
抑制であり、^\n
改行文字を除くすべての文字がスキャン セットの一部であることを意味します。
ただし、数値の直後に改行がある場合、これは古いスタイルの入力では失敗します。sscanf()
より堅牢な方法は、最初に行全体をバッファーに読み込み、次にorを使用してバッファーを解析することstrtol()
です。
char buf[MAX_LINE_LENGTH];
if (fgets(buf, sizeof(buf), fpin) != 0) {
if (sscanf(buf, "%d", &var) == 1) {
/* ... */
} else {
/* ...handle parse error */
}
} else {
/* ...handle file read error */
}
getline()
C++ では、 と を使用して同様に実行できますistringstream
。
std::string line;
std::istringstream iss;
if (std::getline(std::cin, line)) {
iss.str(line);
if (iss >> var) {
//...
} else {
//...handle scan error
}
} else {
//...handle read error
}
コメントでは、次のように尋ねます。
すべてのcinを異なるパラメータに割り当てる方法は?
各コメントが値の意味を説明している場合、 を使用しmap<string, int>
て名前と値の関連付けを作成できます。コメントは通常の形式に従っていないため、解析には注意が必要です。
C バージョンでは、配列を使用して関連付けを格納します。その後、( を使用して) ソートqsort()
し、ルックアップを実行する必要があるときに ( を使用して) 二分探索を実行できますbsearch()
。
struct value_item {
char name[MAX_NAME_SIZE];
int value;
};
struct value_item value_map[MAX_VALUE_MAP];
size_t value_map_size = 0;
while (fgets(buf, sizeof(buf), fpin) != 0) {
const char *slash2 = strstr(buf, "//");
if (slash2 && slash2[2] != '\0') {
sscanf(buf, "%d", &value_map[value_map_size].value);
sscanf(slash2+2, "%s", value_map[value_map_size].name);
++value_map_size;
} else {
/* ...handle parse error */
}
}
C++ バージョンも同様です。C++ にはmap
、関連付けを簡単に作成するために使用できる が用意されています。
std::map<std::string, int> value_map;
while (std::getline(std::cin, line)) {
std::string::size_type n = line.find("//");
if (n != std::string::npos && line.size() > (n+2)) {
int value;
std::string name;
iss.str(line);
iss >> value;
iss.str(line.substr(n+2));
iss >> name;
value_map[name] = value;
} else {
//...handle parse error
}
}
私はこれを頭の上から書いているので、エラーやより良い方法があるかもしれません. しかし、これで一般的なアイデアが得られるはずです。