scanfで複数(具体的な数は不明)の文字列を入力し、処理するプログラムはどう作ればよいのですか?

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

scanfで複数(具体的な数は不明)の文字列を入力し、処理するプログラムはどう作ればよいのですか?

#1

投稿記事 by po_po » 8年前

入力する側が任意の数だけ文字列を入力し、その文字列一つ一つについて関数に入れて処理をするプログラムを作りたいのですが、scanfで入力を複数、任意の数だけ受け付けるプログラムの作り方がわかりません。
入力の際、何個の入力をするかの具体的な数の入力を受け付けない場合、どのような構成でプログラムを書けばいいのでしょうか?

yoko
記事: 24
登録日時: 13年前

Re: scanfで複数(具体的な数は不明)の文字列を入力し、処理するプログラムはどう作ればよいのですか?

#2

投稿記事 by yoko » 8年前

よくあるのが、
do whileでループし、特定の値が入力されたら入力を終了するというのがあります。

コード:

do{
     scanf("%s",変数)
}while(変数==終了値);
どのタイミングで関数を呼ぶのかわかりませんが、
入力がすべて完了した後の場合は文字列の配列(char[][])に値を代入させ、
入力直後に毎回関数を呼ぶ場合は文字列の変数(char[])に代入させればいいと思います。


※言語の指定がなかったため、C言語であると想定して回答しています。

po_po
記事: 38
登録日時: 8年前

Re: scanfで複数(具体的な数は不明)の文字列を入力し、処理するプログラムはどう作ればよいのですか?

#3

投稿記事 by po_po » 8年前

すいません指定し忘れてましたがC言語についての質問です。
回答ありがとうございます。
でも今回知りたいのは純粋に文字列だけ入力して処理させたいのです。
ループを終了させる条件のためno特定の値を入力するといったような操作はできない場合どうしたらいいのでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: scanfで複数(具体的な数は不明)の文字列を入力し、処理するプログラムはどう作ればよいのですか?

#4

投稿記事 by みけCAT » 8年前

何がしたいのかよくわかりませんが、こんな感じでしょうか?

コード:

#include <stdio.h>
#include <stdlib.h>

/* 線形リストの1要素あたりのバッファサイズ */
#define BUFFER_SIZE 512

/* 入力した文字列を一時的に格納しておく線形リスト */
typedef struct buffer_tag {
	char buf[BUFFER_SIZE];
	struct buffer_tag *next;
} buffer_t;

/* 線形リストを開放する */
void free_buffer(buffer_t *buf) {
	while (buf != NULL) {
		buffer_t *next = buf->next;
		free(buf);
		buf = next;
	}
}

/* 標準入力から文字列を読み込み、その文字列へのポインタを返す。
 * 文字列は改行区切りと仮定した。
 * 読み込めなかった場合はNULLを返す。
 */
char *read_string(void) {
	/* 最新の要素に格納している文字数 */
	size_t current_buffer_size = 0;
	/* この入力全体の文字数 */
	size_t all_buffer_size = 0;
	/* ループ変数 */
	size_t i;
	/* バッファの先頭要素 */
	buffer_t *buffer_head = NULL;
	/* バッファの末尾要素 */
	buffer_t **buffer_next = &buffer_head;
	/* 最後に入力した文字 */
	char input = '\0';
	/* 読み込んだ文字列 */
	char *result;

	/* 改行か入力の終わりまで文字列を読み込む */
	while(scanf("%c", &input) == 1 && input != '\n') {
		/* バッファが尽きていたら、次の要素を確保する */
		if (*buffer_next == NULL) {
			*buffer_next = (buffer_t*)malloc(sizeof(buffer_t));
			if (*buffer_next == NULL) {
				free_buffer(buffer_head);
				return NULL;
			}
			(*buffer_next)->next = NULL;
			current_buffer_size = 0;
		}
		/* 入力した文字を格納する */
		(*buffer_next)->buf[current_buffer_size++] = input;
		all_buffer_size++;
		if (current_buffer_size >= BUFFER_SIZE) {
			buffer_next = &(*buffer_next)->next;
			current_buffer_size = 0;
		}
	}

	/* 読み込めなかったかを判定する */
	if (all_buffer_size == 0 && input != '\n') return NULL;

	/* 読み込んだ文字列用のメモリを確保する */
	result = (char*)malloc(sizeof(char) * (all_buffer_size + 1));
	if (result == NULL) {
		free_buffer(buffer_head);
		return NULL;
	}

	/* 線形リストに読み込んだ文字列を結果にコピ−する */
	current_buffer_size = 0;
	buffer_next = &buffer_head;
	for (i = 0; i < all_buffer_size; i++) {
		result[i] = (*buffer_next)->buf[current_buffer_size++];
		if (current_buffer_size >= BUFFER_SIZE) {
			buffer_next = &(*buffer_next)->next;
			current_buffer_size = 0;
		}
	}
	result[all_buffer_size] = '\0';
	free_buffer(buffer_head);
	return result;
}

/* 入力した文字列を入れる関数 */
void kannsuu(const char *input) {
	size_t cnt = 0;
	printf("moziretu = %s\n", input);
	while (input[cnt] != '\0') cnt++;
	printf("length = %u\n", (unsigned int)cnt);
}

int main(void) {
	char *input;
	while((input = read_string()) != NULL) {
		kannsuu(input);
		free(input);
	}
	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ISLe()

Re: scanfで複数(具体的な数は不明)の文字列を入力し、処理するプログラムはどう作ればよいのですか?

#5

投稿記事 by ISLe() » 8年前

scanfの戻り値をチェックすればよいのでは。

コード:

#include <stdio.h>
int main(void)
{
	char str[256+1];
	while (scanf("%256s", str) == 1) { /* 読み込めるあいだ繰り返す */
		printf("[%s]\n", str); /* ひとつずつ関数に渡す */
	}
	return 0;
}
scanfは文字列を空白で区切るので、空白を含めた文字列を扱いたい場合はfgetsを使った行単位の処理になります。

po_po
記事: 38
登録日時: 8年前

Re: scanfで複数(具体的な数は不明)の文字列を入力し、処理するプログラムはどう作ればよいのですか?

#6

投稿記事 by po_po » 8年前

ISLe()様
ありがとうございました。
scanfに戻り値があることを知りませんでした。
書いてくれたプログラムの通りにやったら無事解決しました。
みけCAT様
具体的なプログラムまで書いてくださりありがとうございます。
yoko様
回答ありがとうございました。
今後の参考になりました。

閉鎖

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