C言語による文字列の逆順出力(難問)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Serdol
記事: 9
登録日時: 3年前

C言語による文字列の逆順出力(難問)

#1

投稿記事 by Serdol » 3年前

任意の長さの行入力を受け付け、それを逆順に出力していくプログラムです。 (入力終了の判断はctrl+D)


非表示エリア
この非表示エリアを表示するには、登録し、ログインする必要があります。


入力例
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(改行)
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(改行)
cccccccccccccccccccccccccccc(改行)
出力例
cccccccccccccccccccccccccccc(改行)
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(改行)
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(改行)
非表示エリア
この非表示エリアを表示するには、登録し、ログインする必要があります。
これの4行目の関数の定義がわかりません。わかる方いらっしゃるでしょうか。
最後に編集したユーザー Serdol on 2017年6月26日(月) 15:10 [ 編集 3 回目 ]

アバター
purin52002
記事: 235
登録日時: 4年前
連絡を取る:

Re: 文字列の行ごとの逆順出力(難問)

#2

投稿記事 by purin52002 » 3年前

こんにちは

関数の定義がわからない、とのことですが非表示テキストの中に書いてある処理を書けばいいような気がします。

http://www9.plala.or.jp/sgwr-t/lib/realloc.html
こんなサイトを見つけました。
このサイトではmallocもreallocも使っているので、このコードを参考にできそうです^^

バッファの長さ[l]を最初に決めて、
を確保し、
getcharなどで文字[c]を一文字ずつ読み込み、
読み込んだ文字の数[n]が[l]より大きくなったら、
[l]を長くして、一時バッファ[t]を[l]の長さで確保して、
に[t]を割り当てて、
NULL文字まで読んだら、
[l]を[n]と同じ値にして、
[t]を[l]の長さで確保してに割り当てる。

っていう感じかなあ、って考えました。
(あってるかどうかは知らない^p^)

[l]を長くするときは、ちまちま長くするより、一気に長くしたほうがたぶん処理が早いと思います。
([l]=2,4,16,32,,,のように倍々で長くするとか?)
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

かずま

Re: 文字列の行ごとの逆順出力(難問)

#3

投稿記事 by かずま » 3年前

1行の文字数が確定してから malloc するので、
realloc を必要としない行逆順プログラムです。

コード:

#include <stdio.h>   // getchar, fputs, stdout
#include <stdlib.h>  // malloc, free
 
char *get_ln(int n)
{
    char *p = NULL;
    int c = getchar();
    if (c != EOF || n != 0)
        if (c == EOF || c == '\n')
            (p = malloc(n+2)) && (p[n] = '\n', p[n+1] = '\0');
        else
            (p = get_ln(n+1)) && (p[n] = c);
    return p;
}

char *getline1(void) { return get_ln(0); }

int main(void)
{
    char *p = getline1();
    if (p) main(), fputs(p, stdout), free(p);
}
C++ では main の再帰呼出しは禁止されているので、
あくまでも C のプログラムです。
ちょっと邪悪なコードなので、realloc を使う普通の
プログラムを書くことをお勧めします。
質問への直接の回答でなくて申し訳ありません。

かずま

Re: C言語による文字列の逆順出力(難問)

#4

投稿記事 by かずま » 3年前

No.1 のソースが非表示になっていますね。
アドバイスできません。
なぜ、非表示にしたんですか?

かずま

Re: C言語による文字列の逆順出力(難問)

#5

投稿記事 by かずま » 3年前

realloc版が書けたので回答しようと思ったら、なぜか
質問が改変されていたので、回答するのをやめようか
と思いましたが、せっかく書いたので披露します。

コード:

#include <stdio.h>
#include <stdlib.h>
 
char *getline1(void);
 
typedef struct ListItem {
    char *line;
    struct ListItem *previous;
} ListItem;
 
int main(void)
{
    ListItem *current = NULL, *next = NULL;
    char *line;
    
    while (line = getline1()) {
        if (!(next = malloc(sizeof(ListItem))))
            printf("Not enough memory.\n"), exit(1);
        if (!*line)
            printf("Error in getline1: Pointer to totally empty line!\n"), exit(1);
        next->line = line;
        next->previous = current;
        current = next;
    }
    while (current) {
        printf("%s", current->line);
        next = current->previous;
        free(current->line);
        free(current);
        current = next;
    }
 
    return 0;
}
 
struct String { char *data; int capa, size; };

int add_ch(struct String *p, int c)
{
    if (p->size >= p->capa) {
        char *tmp = realloc(p->data, p->capa *= 2);
        if (!tmp) { free(p->data); return 1; }  // error
        p->data = tmp;
    }
    p->data[p->size++] = c;
    return 0;  // no error
}

char *getline1(void)
{
    struct String s;
    s.capa = 1024, s.size = 0, s.data = malloc(s.capa);
    if (!s.data) return "";  // error

    int c;
    while ((c = getchar()) != EOF || s.size != 0) {
        if (c == EOF || c == '\n') {
            if (add_ch(&s, '\n') || add_ch(&s, '\0')) return "";  // error
            return realloc(s.data, s.size);  // return a line
        }
        if (add_ch(&s, c)) return "";  // error
    }
    free(s.data);
    return NULL;  // EOF
}
説明が欲しければ、どこが分からないのかを質問してください。

かずま

Re: C言語による文字列の逆順出力(難問)

#6

投稿記事 by かずま » 3年前

add_ch() や struct String を使わず、getline1() だけにしてみました。

コード:

char *getline1(void)
{
    int c, capa = 1024, size = 0;
    char *data = malloc(capa);
    if (!data) return "";  // error
    while ((c = getchar()) != EOF || size != 0) {
        if (capa < size + 2) {
            char *tmp = realloc(data, capa *= 2);
            if (!tmp) return free(data), "";  // error
            data = tmp;
        }
        if (c == EOF || c == '\n') {
            data[size++] = '\n', data[size++] = '\0';
            return realloc(data, size); // return a line with just size
        }
        data[size++] = c;
    }
    free(data);
    return NULL;  // EOF
}

Serdol
記事: 9
登録日時: 3年前

Re: C言語による文字列の逆順出力(難問)

#7

投稿記事 by Serdol » 3年前

皆さまありがとうございました。解決しました。

かずま

Re: C言語による文字列の逆順出力(難問)

#8

投稿記事 by かずま » 3年前

Serdol さんが書きました:皆さまありがとうございました。解決しました。
どのようにして解決したのですか?
非表示のテキストに変更したのはなぜですか?
フォーラムルールにの義務行為の順守をお願いします。

返信

“C言語何でも質問掲示板” へ戻る