あなたは既に細かい回答がありますが、考慮すべき点はいくつかあります。あなたは行指向入力方法(fgets
またはgetline
)を使用している場合は、'\n'
または'\r\n'
(DOS/Windowsの場合)行末の読み取りを削除し、fgets
またはgetline
いずれかによって元の行に含まれなければなりません。 (これが、元のファイルの出力に最初の空白行がある理由です)。
行末を削除する簡単な方法は、末尾のいずれかの行末の最初の行を、ヌル終端の文字で上書きすることです。これを行うには、あなたのメイン・プログラム・ロジックは、次のようになります。
while (fgets (str, MAXC, fp)) { /* read each line */
rmcrlf (str); /* trim \r or \n */
strrev (str); /* reverse string */
printf ("%s\n", str); /* output reverse */
}
あなたrmcrlf
次のようになります(キャリッジリターン改行は削除):
/** stip trailing newlines and carraige returns by overwriting with
* null-terminating char. 's' is modified in place.
*/
void rmcrlf (char *s)
{
if (!s || !*s) return; /* validate not NUL and not empty */
char *p = strpbrk (s, "\r\n"); /* locate first line-ending char */
*p = 0; /* set to nul-terminating char */
}
(注:あなたが使用することができstrlen
(またはポインタとループ)を使用して文字列の末尾を検索し、逆方向に処理しますが、は、末尾を検索せずに逆方向に'\n'
または'\r'
のいずれかを検索することができます。
その後、次のようにあなたは一緒にすべてのピースを置くことができ
/** strrev - reverse string 's' in place.
* The original string is not preserved.
* If 's' is not valid, no action taken.
*/
void strrev (char *s)
{
if (!s || !*s) { /* validate s not NUL and not empty */
printf ("strrev() error: invalid string\n");
return;
}
char tmp;
char *begin = s, *end = strrchr (s, 0) - 1;
while (end > begin) {
tmp = *end;
*end-- = *begin;
*begin++ = tmp;
}
}
同じように場所に文字列を逆に(代わりにstrlen
の終わりを見つけることstrrchr
を使用して)することができます。これは同じタスクにアプローチする単純な別の方法です。注:次のコードでは、#define
の代わりにenum
を使用して定数を設定します(代わりの方法を示すため)。また、注意してください:コードは最初の引数として与えられたファイルから読み込まれることを(またはstdin
から、デフォルトでは、ファイル名が与えられていない場合):
#include <stdio.h>
#include <string.h>
enum { MAXC = 256 };
void strrev (char *s);
void rmcrlf (char *s);
int main (int argc, char **argv) {
char str[MAXC] = "";
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file is open */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (str, MAXC, fp)) { /* read each line */
rmcrlf (str); /* trim \r or \n */
strrev (str); /* reverse string */
printf ("%s\n", str); /* output reverse */
}
if (fp != stdin) /* close file (if not stdin) */
fclose (fp);
return 0;
}
/** strrev - reverse string 's' in place.
* The original string is not preserved.
* If 's' is not valid, no action taken.
*/
void strrev (char *s)
{
if (!s || !*s) { /* validate s not NUL and not empty */
printf ("strrev() error: invalid string\n");
return;
}
char tmp;
char *begin = s, *end = strrchr (s, 0) - 1;
while (end > begin) {
tmp = *end;
*end-- = *begin;
*begin++ = tmp;
}
}
/** stip trailing newlines and carraige returns by overwriting with
* null-terminating char. 's' is modified in place.
*/
void rmcrlf (char *s)
{
if (!s || !*s) return;
char *p = strpbrk (s, "\r\n");
*p = 0;
}
例入力
$ cat dat/strtorev.txt
abc def ghi jkl mno pqr
ABC DEF GHI JKL MNO PQR
出力を
$ ./bin/strrev_line <dat/strtorev.txt
rqp onm lkj ihg fed cba
RQP ONM LKJ IHG FED CBA
(注意:ジョナサンはコメントで尋ねたとして、あなたはどちらか上記のように行を逆にするか、各単語を逆にすることができます(例: cba fed ihg...
)は、必要なことが正しく記述されているかどうかを確認してください。
は、ご質問があれば私に教えてください。 `abc`、` def`、 `ghi`:
は、あなたが3行のファイルがあるとします。 'cba'、' fed'、 'ihg'、' ghi'、 'def'、' abc'、あるいは 'ihg'、' fed''、 'cba'を出力する必要がありますか?かかわらず、必要な出力が何であるかの、あなたは、標準のC [ 'のfgets()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fgets.html)またはPOSIX [ 'getlineのを(ルックアップする必要があります) '](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html)を参照してください。次に、必要に応じて逆文字列関数を呼び出します。通常、出力を反転から分離する方がよいことに注意してください。 –
また、 'printf(str)'は悪いです。非常に悪いです。 'printf("%s \ n "、str)'や 'puts(str)'を使うべきです。印刷している文字列に '%'シーケンスが含まれていて、それらの '%s'シーケンスを処理するために' printf() 'に引数を指定しなかった場合、危険です。 –
@JonathanLeffler第2のもの。 abcはcbaになります –