はじめまして!
今、テーブル展開について非常に悩んでいます。
ファイルに記述されている文字列(可変長)を
共有メモリに展開するにはどうしたらいいのか
知っている方がいらしたら教えてもらえませんか?
ちなみに言語はC言語です。
宜しくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

勘違いしてたらゴメンナサイ。


テーブル展開でお悩みとは、要するに可変長列/可変長行のファイルの内容をメモリ上に展開したいがどういうデータ構造にすれば良いか?という意味ですか?
多次元の可変長データならリスト構造が定石かなぁ?
ファイルから1行読んだ後、lengthを取って見合う長さのエリアをallocし、そこにstrcpy、さらにリスト構造体をallocしてそこに前述の文字列の先頭ポインタを代入、次行以降これを繰り返してリスト構造体を繋げていく。
1charづつリスト構造体に入れて2次元リストにする手もありますが、1行分の文字列の登録/抽出処理が面倒になるので、行方向は1本の文字列として上記の様にlengthを見てallocしてしまうのが簡単かと。
こんな文章ではイメージできない!(もっともだ)様でしたら、下記URLなどを参考にして下さい。
最後に、リスト構造はゴミ掃除が大変なのでご注意を。

参考URL:http://www.st.rim.or.jp/~phinloda/cqa/cqa4.html# …
    • good
    • 0
この回答へのお礼

有難う御座いました。
非常に勉強になりました。
又、解らない事があった時は宜しくお願いします。

お礼日時:2001/07/28 16:12

用途によっていろいろやり方があると思うので,


何をしたいかによると思います。

文字列が可変長でも文字列の数が固定かどうかとか、
あとで中身を別の物に長さも変えて入れるかどうかとか、
…。

また、共有メモリを使う場合、単一の領域のみ使うか,
複数使ってもよいか、大きさはどのぐらいにするかでも
違ってくると思います。

OSによっても多少事情がことなるかも知れませんし,
その共有メモリを使うのはどういうプログラムであるか、
いくつのプロセスがそれを同時に使うのかとか。


一応どんな場合でも共通と思うのは,ある程度の大きさを
一度にまとめてとる必要があることです。
malloc()を使う場合は数バイトのを沢山とっても
あまり気にする必要はありませんが、共有メモリの場合は
そうはいきません。
たとえば、256Kbyte領域をとって、その中を自分で
管理して使う、つまり、malloc(),free()に相当する
ことを自分でやる必要があります。
まあ、固定の大きさのテーブルをとるなら、そこまで
やる必要はありませんけど。

これは、共有メモリを管理するのはOSにとっては
かなり負荷の大きいことによります。
だから、領域はまとめて少ない数を使う必要があるわけです。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC++ の typedef の 使い方の質問

C++のtypedefの使い方の質問ですが、typedefは、別名の定義として、知られていますが。
以下のソースの意味がよく読み取れないです。windows プログラミングとC++
が分かるかたがいれば、以下のソースの意味を教えていただきたいです。

よろしくお願いします。
typedef BOOL (WINAPI *AddAccessAllowedAceFn)(
PACL pAcl,
DWORD dwAceRevision,
DWORD AceFlags,
DWORD AccessMask,
PSID pSid
);

Aベストアンサー

関数ポインタの別名定義です。
「関数ポインタ typedef」をキーワードにWeb検索してみてください。
丁寧に解説されているサイトが見つかるでしょう。

QC言語 コンパイル時に決定される固定文字列の長さの記述方法

固定文字列の長さはどのように書いたらよいのでしょう?

"====END====" の文字列長は11ですので、
strlen(ENDMARK); と記述すると、実行時に計算して11を得るコードが生成されますよね。
これを、コンパイル時に数字11に置き換えてくれる記載方法が思いつきません。

つまり、以下のコードでは、strlen(ENDMARK)なので、
 実行時に文字列長を計算するコード
になってしまいます。
これを、コンパイル時に計算して定数11に置き換えるようなコードを書きたいのです。
strlen(ENDMARK)と記載した部分を、どのように書いたらよいのでしょうか?

単純に11に置き換えてしまうと、#define ENDMARK "====END===="を修正した場合に整合性が取れなくなることがあり避けたいのです。
よろしくお願いします。

#define ENDMARK "====END===="

gets(buf);
if( strncmp(buf, ENDMARK, strlen(ENDMARK)) == 0 ) {
:

固定文字列の長さはどのように書いたらよいのでしょう?

"====END====" の文字列長は11ですので、
strlen(ENDMARK); と記述すると、実行時に計算して11を得るコードが生成されますよね。
これを、コンパイル時に数字11に置き換えてくれる記載方法が思いつきません。

つまり、以下のコードでは、strlen(ENDMARK)なので、
 実行時に文字列長を計算するコード
になってしまいます。
これを、コンパイル時に計算して定数11に置き換えるようなコードを書きたいのです。
strlen(ENDMARK)と記載し...続きを読む

Aベストアンサー

sizeof(ENDMARK) とすると1バイト大きい12が得られます。
11が望みなので、
if( strncmp(buf, ENDMARK, sizeof(ENDMARK)-1) == 0 ) { とするか

#define ENDMARKLEN (sizeof(ENDMARK)-1) として
if( strncmp(buf, ENDMARK, ENDMARKLEN) == 0 ) { とするか
のどちらかでよいかと。

QC++.NET の String型の使い方

初めて質問いたします。
C++ .NET 2005 Express Beta版を入手し、Windows Formsのプログラミングを勉強してます。

TextBoxのTextに値を変数で指定したいのですがどうすれば良いのかわかりません。

  textBox1->Text = "Test";
とダイレクトに値を指定すればできるのですが、

  #include <string>
  using namespace std;
   (省略)
  string str = "Test";
  textBox1->Text = str;
は、エラーになってしまいます。

C++標準のstringクラスではなく、.NETはStringクラスがあるようですが、これの使い方がMSDN等で調べているのですが分かりません。
分かりやすいURLなどありましたら教えていただけませんか。

Aベストアンサー

textBox1->Text = new String(str.c_str());
でいけるんじゃないかなあ。
試してないのでなんですが、
C++のstringクラスからは、c_str()で、いわゆるNULL終端文字列へのポインタが得られて
.NETのStringクラスは、NULL終端文字列でのコンストラクタがありますから。

QC言語で取得した文字列を、C++の文字列として取り扱いたいです。

C言語で取得した文字列を、C++の文字列として取り扱いたいです。

皆さんこんにちは。

C言語で取得したchar型で定義された文字列を、
C++の「std::string」に渡したいと思っております。
どうすればかなうでしょうか?
具体的には次のような内容です。

■C言語側
----
char key1 = "deperture";
----

■C++側で「key1 = key2」としたいです。
----
std::string key2 = key1;
----

C言語側で記述されている「key1」の値(deperture)を、
C++ソース内の「key2」に渡したいと思っています。

こうゆう場合、どんな方法をとれば適切でしょうか。
C言語側でのchar型の文字列の値を、
C++側の「std::string」型として
C++のソースへ渡す方法が分からないです。

アドバイスいただけるとありがたいです。
簡単な例を頂けると更に大変ありがたいです。

以上どうぞ宜しくお願い致します。

C言語で取得した文字列を、C++の文字列として取り扱いたいです。

皆さんこんにちは。

C言語で取得したchar型で定義された文字列を、
C++の「std::string」に渡したいと思っております。
どうすればかなうでしょうか?
具体的には次のような内容です。

■C言語側
----
char key1 = "deperture";
----

■C++側で「key1 = key2」としたいです。
----
std::string key2 = key1;
----

C言語側で記述されている「key1」の値(deperture)を、
C++ソース内の「key2」に渡したいと思っています。

...続きを読む

Aベストアンサー

> char key1 = "deperture";

本当にこれであっていますか?

char key1[] = "deperture";

ではないですか?
そうだとした場合、C++側では、

extern "C" char key1[];
std::string key2(key1);

とすればよいかと思います。

Qc++ stringの使い方

お世話になります。
最近c++始めました。
stringの使い方がよくわかりません。
以下のstringの使い方が問題ないか確認頂けますか。
スマホで書くため、文法が合ってないと思いますが、stringの使い方だけ確認させてください。
引数にstringで囲って渡すのは実装として普通行いますか。
やってはいけないですか。
是非ご教示ください。

#define STR1 "mojiretu"
main()
if(check(string(STR1)))



bool check(string str)

Aベストアンサー

間違っちゃいないけど、直に const string でかまわんのでは?

#include <iostream>
#include <string>

const std::string STR1 = "mojiretu";

bool even_length(const std::string& str) {
return str.length() % 2 == 0;
}

int main() {
if ( even_length(STR1) ) {
std::cout << STR1 << " : even\n";
} else {
std::cout << STR1 << " : odd\n";
}
}

QC言語 構造体(3) 可変長について

質問タイトル「C言語 構造体(2)」で分からない所があります。
aaa.txtを読み込んだ時の最大行の数、最大列の数はどの変数にあたるのでしょうか?たとえば、最大行の数=x,最大列の数=yi=1,j=1として、i=1 to x,j=1 to yとし、ループで全部表示させることが目的です。

printf( "%d行目%d列目は「%s」" , i,j,ReadCsv( &mycsv , i - 1 , j - 1 ) );
としたいのです。

「C言語 構造体(2)」でsha-girlさんより頂いたは
http://oshiete1.goo.ne.jp/kotaeru.php3?q=1216226
No.4です。

よろしくお願い致します

Aベストアンサー

for(i = 1; i <= mycsv.cnt; i++)
for(j = 1; j <= mycsv.line[i].cnt; j++)
printf("%d行目%d列目は「%s」" , i, j, ReadCsv(&mycsv, i - 1, j - 1));


もしくは後々のためにアクセッサ関数を定義してcntを間接的に取得します。

int CountCsvLines(MYCSV *pCsv)
{
return pCsv->cnt;
}

int CountCsvRows(MYCSV *pCsv, int l)
{
if (l >= pCsv->cnt)
return 0;
return pCsv->line[l].cnt;
}

QVisial C++おけるπの使い方

自宅でCプログラミングの練習をするためVisial C++ 2008を使って
プログラムをしています。y<sin(πx)となった時の
割合などを計算するプログラムで                「M_PIが定義されていない識別子です」
とでてきます。所持している本を参考にしてもM_PI=πとして用いる
と書いてあり、math.hもインクルードしてるので原因が分からなくて
困ってます。Visial c++ではπの使い方には何か別の使い方がある
のでしょうか?よろしくお願いします。
*↓が実際に作ったプログラムです。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int main(void){
int i,n,count=0;
double x,y,r,error;

srand((unsigned)time(NULL)); /*乱数の初期化*/

printf("How many trials?");
scanf("&d",&n);

for(i=0;i<n;i++){
x=rand()/(RAND_MAX+1.0);
y=rand()/(RAND_MAX+1.0);

if(y<sin(M_PI*x)){
count++;
}
}

r=(double)count/n; /*キャスト演算子を使用*/
error=2/M_PI-r;

printf("Result is %f (Error: %f)\n",r,error);

return 0;
}

自宅でCプログラミングの練習をするためVisial C++ 2008を使って
プログラムをしています。y<sin(πx)となった時の
割合などを計算するプログラムで                「M_PIが定義されていない識別子です」
とでてきます。所持している本を参考にしてもM_PI=πとして用いる
と書いてあり、math.hもインクルードしてるので原因が分からなくて
困ってます。Visial c++ではπの使い方には何か別の使い方がある
のでしょうか?よろしくお願いします。
*↓が実際に作ったプログラムです。
#include ...続きを読む

Aベストアンサー

★アドバイス
・math.hをインクルードする前に『_USE_MATH_DEFINES』定数を define します。

#define _USE_MATH_DEFINES
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int main( void )
{
 :
 return 0;
}
必ず include する前に定義して下さい。

QC言語で可変長から固定長に変換方法は??

C言語で可変長から固定長に変換方法は??
ある可変長のファイルがあって、レコード長を全て40にそろいたいと思って以下のようにプログラム作りました:
・・・・・(省略)
len = strlen(buf); // fscanf使ってファイルから読みみ込んだものbufに格納
n = 40-len;
char * str = (char *)malloc(n+1);
memset(str, ' ', n);
strcat(buf,str); //レコード40バイトになるまで空白を詰めていく
fprintf(fpt,buf);//fprintf使って新しいファイルに書き込み
・・・・・・(省略)
実行してみたところ、全部40という長さになっていない、40超えるものも多数出ました。
これは何がだめですか?fprintfをつかったからだめですか?それともmalloc freeにする必要ありますか?まったく検討つかないです。どうかよろしくお願いします

Aベストアンサー

>while(fgets(buf,REC,fp)!= NULL){
>len = strlen(buf);
>printf("レコード長 :%d\n",len);
>}
>結果は
>レコード長 :39
>レコード長 :2

よくあるミスです。

fgetsの2番目の引数は「文字列の終端文字であるヌル文字を格納する分を含んだ、バッファの実サイズ」を指定する事になっています。

そして、困った事に「改行文字は、文字列の文字数に含み、改行文字も読み込む」のです。

では、質問者さんのプログラムを検証してみましょう。

while(fgets(buf,REC,fp)!= NULL){
RECは40です。そのため、fgetsは「bufが一杯になる39文字までを読んで、読み込みを打ち切り、末尾にヌル文字を付加」します。

len = strlen(buf);
bufには「39文字+終端のヌル文字」が入っているので、strlenは終端のヌル文字の手前にある文字数の「39」を返し、lenは39になります。

printf("レコード長 :%d\n",len);
printfは「レコード長 :39+改行」を表示します。

while(fgets(buf,REC,fp)!= NULL){
RECは40です。そのため、fgetsは「さっき読み残した1文字と、改行文字を読んで打ち切り、末尾、つまり改行文字の後にヌル文字を付加」します。

len = strlen(buf);
bufには「読み残した1文字+改行文字1文字+終端のヌル文字」が入っているので、strlenは終端のヌル文字の手前にある文字数の「2」を返し、lenは2になります。

printf("レコード長 :%d\n",len);
printfは「レコード長 :2+改行」を表示します。

結果、質問者さんのプログラムは

レコード長 :39
レコード長 :2

を表示する事になります。

これは「意図した結果ではないが、fgets()関数の仕様通りの動作」であり「正常に動作している」のです。

単に「意図通りの引数を指定しなかった為、意図した動きをしなかっただけ」なのですね。

そういう訳で「40文字+改行1文字+終端ヌル1文字」で、バッファは42バイト必要で、fgetsには「42文字あるバッファ」と「42」を指定しなければならないのです。

レコード長の定義として「#define REC 40」と定義しているのなら、以下のように書かねばなりません。

#define REC 40
char buf[REC + 2] /* 改行文字と終端ヌル文字も格納できるように、レコード長より2文字分大きいバッファを用意しなければならない */
(途中省略)
while(fgets(buf,siziof(buf),fp)!= NULL){ /* fgetsの第2引数に定数は指定しない事。必ず「sizeof(指定したバッファ)を指定すること */
len = strlen(buf);
if (buf[len - 1] == '\n') buf[--len] = '\0'; /* 末尾に改行があるなら、末尾の改行を終端文字ヌルで上書きして取り去り、その分、lenを1減らす */
printf("レコード長 :%d\n",len);
}

>while(fgets(buf,REC,fp)!= NULL){
>len = strlen(buf);
>printf("レコード長 :%d\n",len);
>}
>結果は
>レコード長 :39
>レコード長 :2

よくあるミスです。

fgetsの2番目の引数は「文字列の終端文字であるヌル文字を格納する分を含んだ、バッファの実サイズ」を指定する事になっています。

そして、困った事に「改行文字は、文字列の文字数に含み、改行文字も読み込む」のです。

では、質問者さんのプログラムを検証してみましょう。

while(fgets(buf,REC,fp)!= NULL){
RECは40...続きを読む

QcygwinでのC++の使い方

cygwinでC言語で書いたプログラムを実行したいのですがcygwinを起動すると
私の名前@なにやらアルファベット
が表示され次の行に

と表示されるんですがこの後にどんなことを書けば
#include<・・・>
としてC++のプログラムを書いていくことができるんですか?そもそもcygwinの使い方が根本的に違うんですかねえ?それともメモ帳かなんかにプログラムを書き保存しそれをcygwinで実行するんですかねえ?とりあえずプログラムを実行できるようにしてください。おねがいします。

Aベストアンサー

> それともメモ帳かなんかにプログラムを書き保存しそれをcygwinで実行するんですかねえ?

おおむねその通りです。

メモ帳でも何でもよいので、エディタでソースファイルを作成してください。作成したソースファイルは、とりあえずホームディレクトリに格納するとよいでしょう(C:\cygwinにCygwinをインストールしたのであれば、C:\cygwin\home\アカウント名がホームディレクトリになります)。

作成したソースファイルがfoo.cppだった場合、

g++ foo.cpp

とすれば、a.exeという実行ファイルが同じディレクトリにできるはずです。そこで、

./a

と入力すれば、a.exeを実行することができます。

QC++言語の非常に初歩的な質問(数表)

今、C++言語を勉強中です。
そこで数表を作るみたいな例題があるのですがどうしても思ったとおりになってくれません。
いろんなことを考えましたが自分の力ではどうにもなりません・・・・。
そこで間違いがあれば指摘していただけたらと思い質問させていただきます。
以下がそのプログラム?です。よろしくお願いします。

#include<iostream.h>
#include<math.h>
#include<iomanip.h>
main()
{
int n ; double n3 , n5;

cout << setw(5) << "n"
<< setw(10) << "1/n"
<< setw(10) << "n^1/3" << "\n";
cout << setiosflags(ios::fixed);
for(n=1 ; n<=25 ; ++n)
{
n3=1/n ; n5=pow(n,1/3) ;

cout << setw(5) << n
<< setw(10)
<< setprecision(5) << n3
<< setw(10)
<< setprecision(5) << n5 << "\n" ;
}
return 0 ;
}

今、C++言語を勉強中です。
そこで数表を作るみたいな例題があるのですがどうしても思ったとおりになってくれません。
いろんなことを考えましたが自分の力ではどうにもなりません・・・・。
そこで間違いがあれば指摘していただけたらと思い質問させていただきます。
以下がそのプログラム?です。よろしくお願いします。

#include<iostream.h>
#include<math.h>
#include<iomanip.h>
main()
{
int n ; double n3 , n5;

cout << setw(5) << "n"
<< setw(10) << "1/n"
<< setw(10) << "n^1/3"...続きを読む

Aベストアンサー

整数型のせいで桁落ちしているとか。
n3、n5の計算式をdoubleでキャストしてみてはどうでしょう。
n5=pow((double)n,(double)1/3) ;


人気Q&Aランキング

おすすめ情報