参照渡しとchar*型

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
bitter_orange

参照渡しとchar*型

#1

投稿記事 by bitter_orange » 16年前

お世話になっております。
C言語でcsvファイルから文字列(char*)を読み込みそれを参照渡ししたいのですがうまくいきません。
コードは下記の通りです。

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

#pragma warning (disable:4996)

/* ファイルの読み込み */
static short File_Read(unsigned char* data, long* size)
{
FILE *fp;

	if(!(fp = fopen("name.csv", "rb"))){[pre]
		perror("name.csvが開けません");
		return -1;
}

fseek(fp, 0, SEEK_END); // ファイルの最後にポインタを指定する
*size = ftell(fp); // ファイル自体のサイズを調べる
fseek(fp, 0, SEEK_SET); // 読み込むためにファイルの最初にポインタを指定する
data = (unsigned char*)malloc(*size);
fread(&(*data), 1, *size, fp); // 読み込み

fclose(fp); // ファイルを閉じる

return 0;[/pre]
}

/* メイン */
short main(int argv,char* argc[/url])
{
long loop = 0, size = 0;
	unsigned char* data = NULL;

	if(File_Read(&(*data), &size))[pre]
		return -1;
for(loop = 0; loop < size; loop++)
printf("%s\n", data);
puts("");

free(data);

return 0;[/pre]
}

どのようにしたら、参照渡しができるのでしょうか?

あと、もう一つ気になったのですが、このプログラムの途中に malloc 関数を使ってますが、
使わないとデバッグエラーが起こります。
思いつきで malloc 関数を使ってみたらうまくいった、という状態なので理由がよくわかりません。
なぜ malloc 関数が必要なのでしょうか?

OSは[Windows Vista]で開発環境は[Microsoft Visual C++ 2008 Express Edition]です。

よろしくお願いします。

box

Re:参照渡しとchar*型

#2

投稿記事 by box » 16年前

本題の前に、ひとつ質問します。

int n = 123;
int *p;

という定義があるとします。
このとき、p が n を指すようにするには、
この後にどういう文を書けばよいでしょうか?

bitter_orange

Re:参照渡しとchar*型

#3

投稿記事 by bitter_orange » 16年前

box様
プログラムにしてみました。

#include <stdio.h>

int main(void)
{
int n = 123;
	int* p;

	p = &n;

	printf("%d", *p);

	*p *= 10;
	printf("%d\n", n);
}

このように
p = &n
だと思います。

box

Re:参照渡しとchar*型

#4

投稿記事 by box » 16年前

では、本題です。

main関数の
>	if(File_Read(&(*data), &size))

や、File_Read関数の
>	fread(&(*data), 1, *size, fp);	// 読み込み

での &(*data) という表記は、単に data と書いたのと同じである、
ということはわかりますか?

bitter_orange

Re:参照渡しとchar*型

#5

投稿記事 by bitter_orange » 16年前

はい、わかります。

癖で書いてしまいました・・・

自分なりにポインタに関連しているということをわかりやすくするためにそうしてあります。

non

Re:参照渡しとchar*型

#6

投稿記事 by non » 16年前

File_Readで読み込んだデータを格納する領域を確保するのにmallocを使っているわけですよね。
そして、その領域の先頭アドレスを返している。

もし、関数側でauto型の変数を用意し、そのアドレスを返しても、関数から戻ったときにその
領域が使えなくなるからです。呼び出し側の関数で領域を確保するか、グローバル変数にするか
このようにmallocしてヒープ領域に確保するか、staticにして静的領域にとるかしないといけない
からです。

さて、もう一つの質問
>C言語でcsvファイルから文字列(char*)を読み込みそれを参照渡ししたいのですがうまくいきません。
どういう意味ですか?
呼び出し側の関数で領域を確保するか、グローバル変数にするかってことですかね?

box

Re:参照渡しとchar*型

#7

投稿記事 by box » 16年前

端的に言いまして、質問者さんのソースは、下記と同じことをしています。
つまり、呼び出された関数の中で行なったことが、呼び出し元に反映できていないのです。
なぜなら、関数を呼び出すときに、中身を変更したい変数(下例ではp)のアドレスを渡していないためです。


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

void func(char *p)
{
    p = malloc(100);
    strcpy(p, "xyz");
    printf("【func】p=%s\n", p);
}

int main(void)
{
    char *p = "abc";

    printf("【main】func関数実行前のp=%s\n", p);
    func(p);
    printf("【main】func関数実行後のp=%s\n", p);

    free(p);
    return 0;
}

bitter_orange

Re:参照渡しとchar*型

#8

投稿記事 by bitter_orange » 16年前

non様
box様
解説ありがとうございます。

non様
確かにauto型なので戻った時におかしくなってします。
そこは気づきませんでした。ご指摘ありがとうございます。
しかし、main関数に戻る前に File_Read 関数の fread 関数でデバッグエラーが起きてしまいます。
(説明不足で申し訳ありません)

>さて、もう一つの質問
>>C言語でcsvファイルから文字列(char*)を読み込みそれを参照渡ししたいのですがうまくいきません。
>どういう意味ですか?
>呼び出し側の関数で領域を確保するか、グローバル変数にするかってことですかね?
下記のように送った先の関数で値をうまく変化させられません。

#include <stdio.h>

void add(int a, int *b)
{
a += 10;	// 値渡し
	*b += 10;	// 参照渡し
}

int main(void)
{
int a = 0, b = 0;

	add(a, &b);

	printf("%d %d\n", a, b);
}

box様
はい、アドレスが渡せないのはわかっていますが、char* strのようなポインタがあると、
アドレスを渡す方法がよくわかりません。
インターネットで調べても私が見た限り char[100]のような 配列で行っているので、わかりません。
どのようにすればよいのでしょうか?

non

Re:参照渡しとchar*型

#9

投稿記事 by non » 16年前

ああ、そういうことですか。よくプログラムを見ていませんでした。失礼しました。

non

Re:参照渡しとchar*型

#10

投稿記事 by non » 16年前

return data
で確保したアドレスを返します。

non

Re:参照渡しとchar*型

#11

投稿記事 by non » 16年前

ごめんなさい。参照渡しでないといけないのですね。
boxさんのプログラムを使わせてもらうと、
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void func(char **p)
{
    *p = malloc(100);
    strcpy(*p, "xyz");
    printf("【func】p=%s\n", *p);
}

int main(void)
{
    char *p = "abc";

    printf("【main】func関数実行前のp=%s\n", p);
    func(&p);
    printf("【main】func関数実行後のp=%s\n", p);
    free(p);
    return 0;
}

bitter_orange

Re:参照渡しとchar*型

#12

投稿記事 by bitter_orange » 16年前

non様
サンプルコード等ありがとうございます。
ポインタのポインタの存在は知っていましたがこうやって使うんですね。
正しく表示されました。


box様とnon様、何度も本当にありがとうございました。

閉鎖

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