私はK&Rの本に取り組んでいます。主に時間がないため、演習よりも先に読みました。私は追いついてきて、チュートリアルである第 1 章からほとんどすべての演習を完了しました。
私の問題は演習1-18でした。演習は次のとおりです。
入力行から末尾の空白とタブを削除し、空白行全体を削除するプログラムを作成してください
私のコード(以下)はそれを行い、機能します。それに関する私の問題は、私が実装したトリム方法です。それは...間違っている...どういうわけか感じます。たとえば、コード レビューで C# の同様のコードを見たら、私は気が狂ってしまうでしょう。(C# は私の専門の 1 つです。)
これをクリーンアップするためのアドバイスを誰か提供できますか? アドバイスは K & R の第 1 章の知識のみを使用する必要があるというキャッチフレーズがあります (完全な C ライブラリを使用してこれをクリーンアップする方法は無数にあることを私は知っています。ここでは、第 1 章と基本的な stdio.h について話しているだけです。) また、アドバイスをする際に、それが役立つ理由を説明していただけますか? (結局のところ、私は学ぼうとしています! そして、ここの専門家よりも学ぶのに適した人はいますか?)
#include <stdio.h>
#define MAXLINE 1000
int getline(char line[], int max);
void trim(char line[], char ret[]);
int main()
{
char line[MAXLINE];
char out[MAXLINE];
int length;
while ((length = getline(line, MAXLINE)) > 0)
{
trim(line, out);
printf("%s", out);
}
return 0;
}
int getline(char line[], int max)
{
int c, i;
for (i = 0; i < max - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
line[i] = c;
if (c == '\n')
{
line[i] = c;
++i;
}
line[i] = '\0';
return i;
}
void trim(char line[], char ret[])
{
int i = 0;
while ((ret[i] = line[i]) != '\0')
++i;
if (i == 1)
{
// Special case to remove entirely blank line
ret[0] = '\0';
return;
}
for ( ; i >= 0; --i)
{
if (ret[i] == ' ' || ret[i] == '\t')
ret[i] = '\0';
else if (ret[i] != '\0' && ret[i] != '\r' && ret[i] != '\n')
break;
}
for (i = 0; i < MAXLINE; ++i)
{
if (ret[i] == '\n')
{
break;
}
else if (ret[i] == '\0')
{
ret[i] = '\n';
ret[i + 1] = '\0';
break;
}
}
}
編集: ここに表示されているすべての役立つヒントに感謝します。私はまだ C の初心者であり、具体的にはまだポインターに到達していないことを人々に思い出させたいと思います。(K&R の Ch.1 について少し覚えておいてください -- Ch.1 はポインターを実行しません。) 私はそれらの解決策のいくつかを「ちょっと」得ましたが、それらはまだ私がいる場所に対して少し進んでいます ...
そして、私が探しているもののほとんどは、trim メソッド自体です。具体的には、3回ループしているという事実です (とても汚れているように感じます)。私がもう少し賢ければ (C の高度な知識がなくても)、これはもっときれいだったかもしれません。