• ベストアンサー

検索がうまくいきません(pascal)

名前と電話番号を外部環境'teldata'に出力し、検索したい人の名前を入力し対応する電話番号を答えるプログラムを作りました(登録されてなければ「該当者なし」と出力、'end'が入力されるまで続く)。 コンパイルは通ったのですが検索結果はおかしなものになってしまいました。 どこが間違っているのか、ご教授ください。 ソース) program kadai(input,output,meibo); type KojinData = record name : packed array[1..20] of char; tel : packed array[1..15] of char end; var meibo : file of KojinData; x : KojinData; begin rewrite( meibo,'teldata' ); write('名前:'); readln(x.name); repeat write('電話番号:'); readln( x.tel ); write( meibo,x); write('名前:'); readln( x.name ) until (x.name='end'); reset( meibo,'teldata' ); write('名前:'); readln(x.name); repeat while not eof( meibo ) do begin read( meibo,x ) end; if x.name = x.name then begin writeln('電話番号:',x.tel) end else begin writeln('該当者なし') end until (x.name='end') end. 結果) 名前:a 電話番号:1 名前:b 電話番号:2 名前:c 電話番号:3 名前:end 名前:a 電話番号:3 電話番号:3 電話番号:3 電話番号:3 {強制終了するまで続く}

  • rurur
  • お礼率50% (24/48)

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

後ろの repeat の中が変です. まず, せっかく入力してもらった「名前」を, そのあとの read で潰してます. さらに, teldata に書き出したデータも最後の 1個を除いて無視しちゃっています. とどめに if の条件をよく見てください.

rurur
質問者

補足

readでデータを全て読み出して記憶し、入力した名前が含まれてるか判定する、と考えたのですがそうはできないのですね・・・。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

ちょっと考えてほしいのですが, 「全てのデータを読み出してから比較する」必要はありますか?

rurur
質問者

お礼

「1つ読み出してそのつど確認する」のを終りまで繰り返す、ようにプログラムして大体はできました。 まだ少し改良したい点はありますがそこは自分でなんとかしようと思います。 アドバイス、ありがとうございました。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

ここで探す名前を入力 > write('名前:'); > readln(x.name); ... (1) ファイルからデータを取り出している > while not eof( meibo ) do begin > read( meibo,x ) ... (2) > end; (1)と(2)が同じ変数へ代入している ・・・ これで判定出来ますか =の両辺にある『x.name 』は違う物が存在するのか ・・・ > if x.name = x.name then begin > writeln('電話番号:',x.tel) end > else begin > writeln('該当者なし') end > until (x.name='end')

rurur
質問者

お礼

ご指摘を受けて直し、かなり完成に近いところまでこぎつけました。 まだ残ってるところは自分でなんとか改良したいと思います、アドバイスありがとうございました。

関連するQ&A

  • ファイル型の操作がうまくいきません(pascal)

    名前と電話番号を入力するとそれらのデータを外部環境のファイル'teldata'に出力し、内容を全て表示させるプログラムを作っています。 入力可能な人数は特に定めない・'teldata'はレコード型を成分とするファイル、という条件の下作成したのですがどうしてもエラーが出てしまいます。 どう改善すればいいのかご教授ください。 ソース) program kadai(input,output,meibo);     {line 3} type KojinData = record name : packed array[1..20] of char; tel : packed array[1..15] of char end; var meibo : file of KojinData; x : array[1..100] of KojinData; name : packed array[1..20] of char; tel : packed array[1..15] of char; i : integer; begin rewrite( meibo,'teldata' ); i :=0; write('名前:'); readln( name ); repeat i := i+1; x[i].name := name; write( meibo,x[i].name ); {line 23} write('電話番号'); readln( tel ); x[i].tel := tel; write( meibo,x[i].tel );         {line 27} write('名前:'); readln( name ) until (name='end'); reset( meibo,'teldata' ); while not eof( meibo ) do begin for i := 1 to 100 do begin read( meibo,x[i].name,x[i].tel );    {line 34} writeln( x[i].name,x[i].tel ) end end end. エラーメッセージ) E 25190 line 23 - Type clash: string is incompatible with record ... 25430: Type mismatch in write to non-text file E 25190 line 27 - Type clash: string is incompatible with record ... 25430: Type mismatch in write to non-text file E 25190 line 34 - Type clash: record is incompatible with string E 25420 line 34 - Type mismatch in read from non-text file E 25190 line 34 - Type clash: record is incompatible with string E 25420 line 34 - Type mismatch in read from non-text file 次の課題の「検索したい人の名前を打ち込み対応する電話番号を答える」ようにもしたいので配列xを作り最大100人としています(人数を定めないように組めなかったのでとりあえず)。

  • パスカル→JAVA

    下記のパスカルからJAVAに変えるのですが、わからなくてこまってます。よろしくおねがいします。 { 宣言部 } type ZISU= array[0..99] of real; var n,k :integer; p,VALREAL,VALIMAG: ZISU; { EXTERNAL procedure EVAL ( p:ZISU; n:integer; var VALREAL,VALIMAG:ZISU ); } {$I B:EVAL.SRC} { メ イ ン プ ロ グ ラ ム } begin write(lst,'Input vector'); writeln(lst); read(n); readln; write(lst,' n=',n); writeln(lst); for k:=0 to n-1 do begin read(p[k]); readln; write(lst,p[k]); writeln(lst) end; EVAL(p,n,VALREAL,VALIMAG); writeln(lst); writeln(ist); write(lst,'Output vector [THE DISCRETE FOURIER TRANSFORM]'); writeln(lst); for k:=0 to n-1 do begin write(lst,' ',VALREAL[k],'+(',VALIMAG[k],'*i)'); writeln(lst) end end. 

  • Pascal  insertの使い方

    プログラミングの授業で 整数(integer)を入力して、金額表示のように3桁ごとにコンマを打って文字列(string)として表示せよ。 という問題が出されました。 やってみた結果が下なんですが、insertがまちがってぃて実行されません。どこが間違ってるか教えてもらえませんか。 program prj7_2(input,output); var st,u,con:string[100]; n,i,x:integer; begin writeln('数を入力してください。'); readln(st); n:=length(st); if n<=3 then writeln(st) else begin i:=1; con:=','; repeat x:=n-3*i; u:=insert(con,st,x); until x:<3; writeln(u); end; end.

  • 整順リスト形式の英単語辞書(pascal)

    キーボードから「英文」を読み込み、空白(スペース)を英単語の区切りとみなして英単語辞書を整順リスト形式で作りたいのですがうまくいきません。 ソースとコンパイル結果の間違いは↓にありますが、そもそも v := read( sentences ) なんてのが可能なのかもわかりません。(readは最初から一文字ずつ読むとか聞いたのでこうしたのですが・・・) どなたかご教授ください。 program kadai(input,output); type list = ^mojirec; mojirec = record newword : packed array[1..20] of char; next : list end; var sentences,v : packed array[1..500] of char; p,head : list; procedure insert(var p : list; x : packed array[1..20] of char ); var q : list; begin if p = nil then begin new(p); p^.newword := x; p^.next := nil end else if x < p^.newword then begin q := p; new( p ); p^.newword := x; p^.next := q end else insert( p^.next,x ) end; procedure print( p : list ); begin if p<> nil then begin writeln( p^.newword ); print( p^.next ) end end; begin head := nil; write('英文:'); readln( sentences ); repeat repeat repeat read( sentences ); v := read( sentences ); until( read('') ); insert( head,v ) until ( read('.') ); writeln('英文:'); until ( sentences = '.' ); print( head ) end. In program kadai: E 18240 x undefined on lines 16 19 22 26 E 18240 insert undefined on line 26 終了条件はピリオド単体を読み込んだとき、英文の最後はピリオドを付けるようにとなっています。

  • Pascal言語で小町算

    Pascal言語で、『1~9の順に数字を並べ、+、-を補い式を作り、 値が100になる組み合わせをすべて出力するプログラムを作成せよ(例:12 - 3 - 4 + 5 - 6 + 7 + 89 = 100)。』 という課題が出ました。自分なりに組んでみたのですが、 12個あると聞いたのに、4個しか出力されません><; どこが間違っているのかご教授いただけると幸いですっ ------------------------------------------------------- program KomachiZan(output); var i,s:integer; var sign:array[1..9] of integer; var x,n:longint; begin writeln('< 小町算 -Komachi Zan- >'); for i:=1 to 9 do sign[i]:=-1; repeat x:=0; n:=0; s:=1; for i:=1 to 9 do begin if sign[i]=0 then n:=10*n+1 else begin x:=x+s*n; s:=sign[i]; n:=i; end; end; x:=x+s*n; if x=100 then begin for i:=1 to 9 do begin if sign[i]=1 then write(' + ') else if sign[i]=-1 then write(' - '); write(i); end; writeln(' = 100'); end; i:=9; s:=sign[i]+1; while s>1 do begin sign[i]:=-1; i:=i-1; s:=sign[i]+1; end; sign[i]:=s; until sign[1]>=1; end. -------------------------------------------------------

  • 最大公約数を再帰で求める(pascal)

    入力した整数値の最大公約数を出力するプログラムを再帰呼び出しの形式で作れ、という課題が出ました。 再帰でない形式は下のように作れたのですが、再帰形式がどうしてもできません。どなたかご教授ください。 function gcd(a,b:integer):integer; {関数部} var tmp:integer; begin if a<b then begin tmp:=b; b:=a; a:=tmp end; repeat tmp:=b; b:=a mod b; a:=tmp until b=0; gcd:=a end; repeat {計算部、i=n=入力した個数、max=入力できる最大数} i:=i+1; n:=n+1; data[i]:=x; writeln('値:'); readln(x); until (x=0) or (i=max); if i>=2 then begin p:=gcd(data[1],data[2]); if i>=3 then begin for i:= 3 to n do begin p:=gcd(p,data[i]) end; writeln('最大公約数:',p) end else begin writeln('最大公約数:',p) end;

  • 一月前の日付を求めるプログラム(pascal)

    大学の課題で「一月前の日付を求めるプログラムを作れ。その日が無ければその月の最後の日を示す。」というのが出題されました。12月18日(火)と入力すると11月18日(日)、12月31日(月)なら11月30日(金)となる具合です。 列挙型を用い書いてみたのですが、コンパイルしたら「Type-clash」と出てコンパイルできませんでした。どう改善すべきかアドバイスお願いします。 program calender(input,output); type months=(Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Nov,Oct,Dec); weeks=(Mon,Tue,Wed,Thu,Fri,Sat,Sun); var x,x1,z,z1:char; y,y1,p1,p2,i,r:integer; begin writeln('月:'); readln(x); writeln('日:'); readln(y); writeln('曜日:'); readln(z); if x=Jan then begin x1:=Dec end else begin x1:=pred(x)            {x1=表示する月} end; if y>=29 then if x=Mar then begin y1:=28 end else begin y1:=y             {y1=表示する日} end; case x of May,Jul,Aug,Nov,Dec : p1:=30; Jan,Feb,Apr,Jun,Sep,Oct : p1:=31; Mar : p1:=28 {月の違いによる日数の違い} end; p2:=y-y1;     {日にちの違い} r:=(p1+p2)-trunc((p1+p2)/7)*7; {7で割った余り} for i := 1 to r do z1:=pred(z);          {z1=表示する曜日} writeln(x1,'月',y1,'日',z1,'曜日') end.

  • 2つの年月日の間の日数を求めるプログラム(PASCAL)

     大学の講義で、「2つの年月日を入力し、その年月日の間の日数を求めるプログラムを作成しなさい」という宿題が出たので、下のようにプログラムを作成したところ、…63(最後の行):parse error before '.'というエラーが出たのですが、なぜそのようなエラーが出るのかがわかりません。どう改善すべきか、アドバイスをお願いします。 program ex13(input,output); var year1,year2:1..9999; month1,month2:1..12; y1,y2:1..9999; m1,m2:1..12; d1,d2:1..31; n1,n2:1..9999999; begin writeln('question 13'); writeln('Please key the old date.'); write('Y: '); read(y1); write(' M: '); read(m1); write(' D: '); readln(d1); writeln('Please key the new date.'); write('Y: '); read(y2); write(' M: '); read(m2); write(' D: '); readln(d2); for year1:= 1 to y1 do begin if ((year1 mod 4 = 0) and not (year1 mod 100 = 0)) or (year1 mod 400 = 0) then n1:=n1+366 else n1:=n1+365 end; for month1:= 1 to m1 do begin case month1 of 3,5,7,8,10,12,1: n1:=n1+31; 4,6,9,11: n1:=n1+30; 2: if ((y1 mod 4 = 0) and not (y1 mod 100 = 0)) or (y1 mod 400 = 0) then n1:=n1+29 else n1:=n1+28 end; n1:=n1+d1; for year2:= 1 to y2 do begin if ((year2 mod 4 = 0) and not (year2 mod 100 = 0)) or (year2 mod 400 = 0) then n2:=n2+366 else n2:=n2+365 end; for month2:= 1 to m2 do begin case month2 of 3,5,7,8,10,12,1: n2:=n2+31; 4,6,9,11: n2:=n2+30; 2: if ((y2 mod 4 = 0) and not (y2 mod 100 = 0)) or (y2 mod 400 = 0) then n2:=n2+29 else n2:=n2+28 end; n2:=n2+d2; writeln('Ans.',n2-n1); end.

  • 指定した長さのフィボナッチ数列を出力したい(pascal)

    例えば「長さ:6」と入力すると6桁のフィボナッチ数列の項だけを出力するプログラムを作ってるのですが、意外なところで躓いてしまいました。どこが変なのか教えてください。 program fib_search (input,output); var i,p,x,y : integer; f : array[0..500] of real; function fib(n:integer):integer; begin if(n>=0)and(n<=1) then fib:=1 else fib:=fib(n-1)+fib(n-2); end;{fib} begin writeln('数列の長さ:'); readln(p); x:=0; y:=0; for i:= 1 to 5*p do begin x:= trunc(fib(i)/(10^p)); y:= trunc(fib(i)/(10^(p-1))); if (x=0) and (y>=1) then begin writeln(fib(i)) end end; end. 例えばp=6として、10の6乗で割った数x=0&10の5乗で割った数y>=1 だと6桁、と考えました。1 to 5*p は、ざっと数列を見たところ(桁数×5)項までにその桁の数字はぎりぎり出尽くしている、と考えたからです。 これをコンパイルするとx、y共に「 Replaced '^' with a '+'」と出て、 x:= trunc(fib(i)/10^p); y:= trunc(fib(i)/10^(p-1)) と分母の()を取ると「 Expected ')'」と出てしまいます。 また、「(fib(i))」としても同様「 Replaced '^' with a '+'」と出てしまうのです。

  • Pascal言語

    フィボナッチ数列の項は、その直前の連続する二つの項の和である。 f( n ) = f( n - 1 ) + f( n - 2 ) 但し、 f(0) = 0, f(1) = 1 である。   フィボナッチ数列の連続する項の差の比 z = { f( n - 1 ) - f( n - 2 ) }/ { f( n ) - f( n - 1 ) } は、 n が大きくなれば、ある値に収束する。この値の近似値を求める プログラムを書き、その値を示せ。この値は黄金分割比と呼ばれる。 フィボナッチ数列は関数 fibonacci を作って求め、項は配列に表せ。まず 30 項まで求め、黄金分割比の値が収束していく様子を出力して確かめよ。収束判定のために定数 dif = 1.0 e -6 を宣言し、 連続する z の差の絶対値が dif 以下になったとき、収束したとして計算を終了するプログラムを作りなさい。 この問題について質問なんですが コンパイルはできるんだけど、結果がうまく表示されません。 すみませんがわかる方教えてくれませんか? program pe1_2(input,output); const dif = 1.0e-6; var i,m, g : integer; f, z,q : array [0..500] of real; function fibonacci(n: integer):integer; begin if (n >=0) and (n <=1) then fibonacci:=n else fibonacci:=fibonacci(n-1)+fibonacci(n-2); end; { fibonacci } begin f[i]:=fibonacci(i); writeln('30項まで求めます '); for i :=1 to 30 do begin writeln('f(',i:2,')=',f[i]:1); end; write('m='); readln(m); for i:= 3 to m do repeat z[i]:=(f[i-1]-f[i-2])/(f[i]-f[i-1]); until dif >= z[i]-z[i-1]; writeln(z[i]); {writeln('z(',i:3,')=',z[i]:1,','); } end.

専門家に質問してみよう