• 締切済み

配列のサイズ変更

FILE *fp; char *fname = "test.txt"; unsigned char init[300]; int i = 0; int c; fp = fopen( fname, "r" ); if( fp == NULL ){ printf( "%sファイルが開けません\n", fname ); return -1; } while( (c = fgetc( fp )) != EOF ){ init[i] = c; i = i+1; } fclose( fp ); 自分のプログラムの中のこのようなテキストから文字を読んで配列に格納するような動作の中で、initを大きめにとっておいて配列に格納し終わったら余った空の配列を削除する、という機能を拡張したいのですがどのようにすればいいかわかりません。 どなたか教えていただけないでしょうか?

みんなの回答

  • KEIS050162
  • ベストアンサー率47% (890/1879)
回答No.3

平文のテキストの長さが分からないのであれば、いくら配列を大きくしても限界がありますので、必要最低限(CBCモードは詳しくありませんが、逐次的に暗号化していけば、1ブロック長分+αだけでいけるのでは?)の配列だけ確保しておき、逐次、暗号文を別のテキストに書き出して行く方法はいかがでしょうか? 大雑把には下記のやり方です。 1)暗号キー初期値 2)平文のファイルをオープン、暗号文のファイルを作成 3)平文を1ブロック文読み出す 3)平文1ブロック文の暗号化 ⇒ 次の暗号キー 4)暗号文を1ブロック文を書き出す 5)平文のファイルが空になるまで3)から繰り返し 6)平文、暗号文のファイルをクローズ そうでなければ、既に回答のある通り、malloc()を使う方法となりますが、これを使うとしても最初に定義するサイズをどうするか問題ですね。(ファイルをオープンしてからファイルサイズを検索する方法などはありますが。) http://homepage3.nifty.com/mmgames/c_guide/19-01.html 個人的には前者の方が好みですね。

  • notnot
  • ベストアンサー率47% (4847/10260)
回答No.2

配列の大きさは変更できません。 なぜそんなことをしたいと思ったのかを書くと、役立つアドバイスがもらえるかもしれません。

Whalen
質問者

補足

回答ありがとうございます。 AESの暗号化、復号を行うプログラムを作成しているのですが、その機能としてファイルから文字を読みだして配列に格納→そのサイズ/16バイトの回数だけCBCモードで暗号化したいです。 しかし、現状配列のサイズをあらかじめ定義しているため、そのサイズよりテキストが長いと暴走してしまい、それより短すぎると余分な配列が多くなってしまい、暗号化を余分に行ってしまいます。

  • wormhole
  • ベストアンサー率28% (1619/5654)
回答No.1

配列のサイズ変更はできません。 やるとすればmalloc(),realloc()を使っての配列の代用です。

関連するQ&A

  • 配列の長さについて

    現在課題で書いているプログラムに以下のような関数があるのですが、 unsigned char key[32]; int w[60]; int data[NB]; int nk; int nr; int data2[32]; int Cipher(int *); int invCipher(int *); void encryptEBC(int *); void decryptEBC(int *); main(){ unsigned char keys[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; unsigned char iv[]={0xcb,0x70,0x05,0x9e,0x27,0x2f,0x4e,0xd2, 0xd0,0xbe,0x0b,0x06,0xbf,0x16,0xec,0x5a}; unsigned char init2[]={'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0', '1','2','3','4','5','6','7','8','9','0',0x0a}; //unsigned char init2[]={'h','e','l','l','o'}; int isize = sizeof(init2)/sizeof(init2[0]); int dsize2 = sizeof(data2)/sizeof(data2[0]); printf("%d,%d\n",isize,dsize2); FILE *fp; char *fname = "test.txt"; unsigned char init[16]; int i = 0; int c; fp = fopen( fname, "r" ); if( fp == NULL ){ printf( "%sファイルが開けません\n", fname ); return -1; } while( (c = fgetc( fp )) != EOF ){ init[i] = c; i = i+1; } fclose( fp ); memcpy(key,keys,16); nk = 4; nr = nk + 6; KeyExpansion(key); memcpy(data,init,16); memcpy(data2,init2,isize); printf("%d\n",dsize2); datadump("PLAINTEXT: ",data,16); datadump("KEY: ",key,16); Cipher(data); datadump("Cipher: ",data,16); invCipher(data); datadump("invCipher: ",data,16); printf("\n"); printf("%d\n",dsize2); datadump("PLAINTEXT: ",data2,dsize2); encryptEBC(data2); printf("%d\n",dsize2); datadump("EBCCipher: ",data2,dsize2); decryptEBC(data2); datadump("invCipher: ",data2,dsize2); printf("\n"); return 0; } void encryptEBC(int data[]){ int dsize = sizeof(data)/sizeof(data[0]); int tmp[16]; int i,j,k; printf("%d\n",dsize); KeyExpansion(key); for (i = 0; i < dsize; i += 16) { for (j = 0; j < 16; j++){ tmp[j] = data[i + j]; } Cipher(tmp); for(k=0;k<16;k++){ data[i+k] = tmp[k]; } } } 関数encryptEBC内のdsizeの値がこの場合だとmain内の配列data2の長さ32になってほしいのですが、1になってしまいます。 非常に見ずらいプログラムで申し訳ないのですが、どなたか1になってしまう理由、またどうすれば正しくdata2の長さを求められるか教えていただけないでしょうか?

  • テキストファイルの内容を2次元配列に格納したい

    課題で用意されたテキストファイルを読み込み、空白を区切りとする文字列の単位で配列に格納したいのですが、やりかたがわかりません。 ソースプログラムですが #include<stdio.h> #include<string.h> #include<ctype.h> #define MAX 1000 int TextSplit(char *fname, char (*SpStr)[50]); int main(void) { int i, n; char fname[MAX], SpStr[MAX][50]; int Split; FILE *fp; printf("input File =>"); scanf("%s", fname); Split = TextSplit(fname, SpStr); printf("\n %d[文字列数] \n", Split); return 0; } int TextSplit(char *fname, char (*SpStr)[50]) { int i, j, k; char Readstr[MAX]; FILE *fp; fp = fopen(fname, "r"); if(fp == NULL) { printf("ファイルオープン失敗"); return 1; } i = 0; while(fscanf(fp, "%s", SpStr) != EOF) { i++; } fclose(fp); return i; } 以上のソースプログラムですが、内容は「空白で区切る文字列の単位の総数を表示する」ものになっています。 今日の20時までに終わらせないといけないので、ご教授お願いします。 使ってるソフトはMicrosoft Visual Studioです。

  • ファイルサイズを変更したい

    visualstudio2010を使用しています。 c言語で書いているのですが、 test.txt ←abcdefg ファイルサイズ1KB Wtest.txt←書き込み用ファイル 上記のようなファイルがあり、バイナリでtest.txtを読み込みWtest.txtに書き込みたいと思っています。 その際に、1KBのtest.txtを5KBになるまでバイナリで「abcdefg」の後に0を代入したいのですがどう書けば良いのかわかりません。 FILE *fp, *fpw; char *fname = "test.txt"; char *fname_w = "Wtest.txt"; unsigned char buf[10000]; int size; fp = fopen( fname, "rb" ); if( fp == NULL ){ printf( "%sファイルが開けません\n", fname ); return -1; } fpw = fopen(fname_w, "wb"); if(fpw == NULL){ printf( "%sファイルが開けません\n", fname_w ); return -1; } size = fread( buf, sizeof( unsigned char ), sizeof (fp), fp ); /*ここに処理を追加したい*/ fwrite( buf, sizeof( unsigned char ), size, fpw);

  • C言語 strtok

    失礼します。現在こちらでアドバイスを頂きfgetcを使用して配列に格納をすることができたのですが、CSVをカンマ区切りで格納したいのですが上手くいかず困っています。strtokを使用方法をドキュメントを読んでもうまく区切ったものを配列に入れる方法がわかりません 何卒よろしくお願いします。 ソースコード #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include<string.h> #define MAXITEM 1400 int split(char *str, const char *delim, char *outlist[]) { char *tk; int cnt = 0; tk = strtok(str, delim); while (tk != NULL && cnt < MAXITEM) { outlist[cnt++] = tk; tk = strtok(NULL, delim); } return cnt; } int main(void) { FILE *fp; char *fname = "testfile.csv"; char *tp; char *array[1400]; char *test[11][1400]; char c; int i = 0; int n,y; char *tp[1400]; fp = fopen(fname, "r"); if (fp == NULL) { printf("%sファイルが開けません¥n", fname); return -1; } while ((c = fgetc(fp)) != EOF) { array[i] = (char)c; i++; } tp = strtok(array, ","); puts(*tp); while (tp != NULL) { tp = strtok(NULL, ","); if (tp != NULL)puts(tp); } for (n = 0; n < 11; n++) { for (y = 0; y < 1400; y++) { test[n][y] = tp[y]; printf("%c", test[n][y]); } } fclose(fp); return 0; }

  • c言 ファイルのオープンについて

    #include <stdio.h> int main(void) { int ch; FILE *fp; char fname[64]; printf("ファイル名:"); scanf("%s",fname); if((fp=fopen(fname,"r"))==NULL) printf("ファイルをオープンできません。\n"); else{ while((ch=fgetc(fp))!=EOF) putchar(ch); fclose(fp); } return(0); } ファイル名は20130603.cで、実行ファイル(exe)と同じディレクトリに入れてあるのに、このプログラムでファイルをオープンできないのです。 このプログラムを実行するために必要なファイルの作成法と、例としてのファイルの内容、実行結果など、教えていただきたいのです。 色々調べてみたのですが、解決法がイマイチ見つかりませんでした。 どうかよろしくお願いします。

  • ファイル操作

    あるファイルから長さの違った数字や文字を読み込んで配列に格納したいのですが数字などの長さが違うとなんかおかしくなってしまいます; 例えば 1 a 1 2 a 2 3 b 3 4 b 4 などのファイルはできるのですが 0 1 2 3 a 3 4 b 4 5 c 5 の場合5つの配列に格納したいのです。1行目で1つ2行目で1つ3行目の 左、真ん中、右の数字でそれぞれ1つづつ格納したいのです。 それで自分でやったのですが typedef struct path{ int left [100]; int right[100]; char center [100]; }Path; int main(int argc,char *argv[]) { FILE *fp; Path path; int i=0; int first; int second[100]; fp = fopen(argv[1],"r"); while(fscanf(fp,"%d %c %d",&path.left[i],&path.center[i],&path.right[i])==3){ i++; } fclose(fp); このようにやると3行目からはきちんとよみこむのですが1、2行目がうまくできません@@; firstとsecondのそれぞれ1、2行目を入れたいのです。 fscanfをもう1つ増やすしてもやってみましたがうまくいきませんでした。 ちなみにfscanf関数のところをならったばかりです。 fgetcとかそのようなのを使うのでしょうか?(よくわからないですけど) よろしくお願いします。ちなみにLinuxでgcc、C言語です。

  • C言語、fgetcを利用しファイルの内容を変数に

    C言語について質問です C言語のfgetcを利用しファイルの内容を変数にいれてそれを返す関数を作っているのですがうまくいきません <!--以下ソース--> char *file_get_contents(char *filename){ FILE *fp; int c; char *return_str; if((fp=fopen(filename,"r"))==NULL) return NULL; while((c=fgetc(fp))!=EOF ){ sprintf(return_str,"%c",c); } fclose(fp); return return_str; } 誰か理由と改善方法を教えてください!

  • txtファイルの文字を配列に格納

    ファイル関数を使ってoutput.txt(txtファイル)の文字を配列に格納するプログラムを作っているのですが、配列に文字を入れられない状態です。 ※参考になるページやアドバイスがあれば宜しくお願い致します。 ■プログラム #include <stdio.h> void main(){ int i; int data[10]; FILE *fp; fp = fopen("output.txt","r"); if(fp == NULL){ printf("ファイルが見つかりません。"); }else{ for(i=0;fp != EOF;i++){ data[i] = fgetc( fp ); } } } ■output.txt 001 100 猫A 好きな物 ねこまんま 002 200 猫B 好きな物 キャットフード

  • 二次元配列のプログラミングが分かりません

    センサからは常に「#(ONかOFFが16)CR」全部で18個の情報が送られてきます。ONは1、OFFは0を返します。 この情報20回分を二次元配列に格納し、排他的論理和を取るプログラムを考えています。 *************************************** 例3回の場合 1回目#1101110000000111CR 2回目#0010110101110100CR 3回目#0110010100010101CR これを縦に排他的論理和を取っていきます。 まず1回目と2回目の排他的論理和をとる 次に2回目と3回目の排他的論理和をとる 最後に全部で1がいくつあったのかを表示 **************************************** このようなプログラムを書きたいです。どのように書いたらいいでしょうか。 <今できているプログラムは以下です> int main(void) { int i=1; int a=0; int A[20][18]; int b,c =0; char* Buffer; FILE *fp1; Buffer = (char*)calloc(1024,sizeof(char)); char port1[10]; sprintf(port1,"COM6"); fp1 = fopen("result.txt","w"); // ファイルを開く /*ポート設定省略*/ /* 配列の初期化*/ for(b=0;b<20;b++){ for(c=0;c<18;c++){ A[b][c]=0; fprintf(fp0,"%2d",A[b][c]); } } fclose(fp0); /********************************* 数を合わせる #が入ったら読み込み残りの17を拾う *********************************/ do{ CommPort1->ReadBytes((unsigned char*)Buffer,1); }while(*Buffer !='#'); CommPort1->ReadBytes((unsigned char*)Buffer+1,17); //残りの17byteを読み込む CommPort1->FlushCommPort(); //データの送受信 for(int i=0;i<20;i++){ //20回分のデータを読みこみ、テキスト出力 tuushin(Buffer); n++; fprintf(fp1,"%d=%s \n",n,Buffer); } fclose(fp1); return 0; } /**************************************************** 通信する関数 「#(ONかOFFが16個)endコード」、計18からなる文字列を読み込み表示 ****************************************************/ void tuushin(char*Buffer) { CommPort1->ReadBytes((unsigned char*)Buffer,18); CommPort1->FlushCommPort(); printf("%s\n",Buffer); } どのようにかけばいいのか分からないので、教えてください。

  • Ç言語でファイルサイズを変更するプログラム

    Ç言語初心者です。visualstudio2010を使用しています。 ファイルサイズ100MBのtest.binをバイナリモードで開き、10GBになるまで0を追加するプログラムを組みたいと思います。 ファイルを読み込んで出力するようには組めたのですが、この手法だとファイルサイズが大きいと時間がかかってしまいます。 現在のソースは以下の様になっているのですが、どうしたらもっと早く終わらせることが出来るでしょうか? また、int型でファイルサイズを取得していますが、ファイルサイズがもっと大きくなったときにint型では足りなくなってしまうのもどうすればいいのか困っています。 ※元ファイルサイズ(test.bin)は例としています。今後?GBサイズになると思います。変更後のファイルサイズは今後10GBくらいまでで考えています。 #include <stdio.h> #include <string.h> #include "stdafx.h" #define KIRO (1024) #define MEGA (KIRO*1024) #define GIGA (MEGA*1024) #define SIZE (100) int main(void) { FILE *fp,*fpw; unsigned char c; unsigned char zero = 0; int i = 0; int filesize; // 元ファイルをバイナリモードで開く fp = fopen( "test.bin", "rb" ); if( fp == NULL ) { printf( "test.binが開けません" ); return 1; } fseek( fp, 0, SEEK_END ); filesize = ftell( fp ); fseek( fp, 0, SEEK_SET ); // 書込み先をバイナリモードで開く fpw = fopen( "test_W.bin", "wb" ); if( fp == NULL ) { printf( "test_W.binが開けません" ); return 1; } while(1) { i++; // 指定サイズになったら終了 if(i > MEGA * SIZE) break; // ファイルサイズまで読み書き if(filesize < i){ // 残りを0で代入 fwrite(&zero, sizeof(unsigned char), 1, fpw); /* 1文字ずつ書き込み */ }else{ // ファイルの内容を1文字ずつ読み書き fread( &c, sizeof(unsigned char), 1, fp ); /* 1文字ずつ読み込み */ fwrite(&c, sizeof(unsigned char), 1, fpw); /* 1文字ずつ書き込み */ } printf( "%d番目\n", i ); } printf( "\n" ); fclose(fp); fclose(fpw); return 0; }

専門家に質問してみよう