23481 34958 432 ・・・  
83829 93828 210 ・・・  
  ・     ・    ・
  ・     ・    ・
  ・     ・    ・
上の様に各列に対して決まったビット数で表示されている数値のデータの
一番最後の桁(一番上の行なら 1、8、2)を消去するプログラムを
作りたいのですが、
各数値の間にスペースがあるので、ヌルコードの一つ手前の数値を消去すると考えたほうが良いのか、それともビット数(桁数)が決まっているので各列に対して最後の桁を指定して消去した方が良いのでしょうか?
また、その「消去する」という
プログラムには何の関数を使ったら良いのでしょうか?

このプログラムへの取っ掛りが見つからず、困っています。よろしくお願いします。

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

A 回答 (3件)

データの間にスペースがあるので、このデータがファイルにあると仮定します。


1.1行読み込む(fgets)
2.スペース区切りでデータを区切る(strtok)
3.区切った文字列("23481\0")の最後にNULLをセット
  buff[strlen(buff)-1] = NULL;
4.2へNULLまで繰り返す。
5.1行別ファイルに書き出す。
6.1へEOFまで繰り返す。
簡単なロジックかいてみました。
コンパイルもしてませんので、動くかどうかわかりません。
また、エラー回避も入れてません。
試して検証して、改造してご利用ください。

FILE *fpw, *fpr;
char buff[1025];
char bf[6];

fpr = fopen("read.txt", "r");
fpw = fopen("write.txt", "w");
while(fgets(buff, 1024, fpr)) {
tok = strtok(buff, " ");
if (!tok) exit(-1);
strcpy(bf, tok);
bf[strlen(bf)-1]=NULL;
fprintf(fpw, "%s", bf);
while(tok=strtok(NULL," ")) {
strcpy(bf, tok);
bf[strlen(bf)-1]=NULL;
fprintf(fpw, " %s", bf);
}
fprintf(fpw, "\n");
}
    • good
    • 0
この回答へのお礼

アドバイスありがとうございます!
解説付きのロジックなんて本当に助かります。
有効に使わせていただきます。

お礼日時:2002/03/21 22:05

ご質問の数値というのは、char型で格納されている文字列なのでしょうか?


それとも、intやlongなどで数値型で格納されているのでしょうか?
「決まったビット数で表示されている」というのも意味がよくわかりません。「決まったバイト数(桁数)で何らかの領域に格納されている」ってことでしょうか?

領域に格納された数文字列の最後の1桁を消去すると判断して、私が思いつく方法としては、
1列目のデータの先頭から、strrchr関数でヌルコードを検索しながら、strncatで数字列の長さ-1のサイズで別の用意しておいた領域にコピーして行く。
って感じでしょうか。
関数については、リファレンスで確認してください。

この回答への補足

質問する側としてのマナーを無視した質問の仕方をしてしまい
申し訳ありませんでした。

数値は、文字列で、おっしゃる通りに決まったバイト数で格納されています。

補足日時:2002/03/21 13:13
    • good
    • 0

データは、文字列ですか?


ファイルからの読み込みですか?それとも電文?
1行のデータ数は決まっていますか?
行の終端は\nですか?NULLですか?

その辺がわからないと答え様が無いです。

この回答への補足

質問するにあたって、最低限の情報を言わずに質問してしまい
申し訳ありませんでした。
ちなみにデータは、ファイルからの読み込みです。
1行のデータ数は決まっています。
行の終端については、¥nです。

補足日時:2002/03/21 13:07
    • good
    • 0

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

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

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

Q4桁の数値を逆に表示されるプログラム

プログラミングで分からないところがあるので、教えてください
4桁の数値を入力し、その数値が逆に表示されるプログラムを作成したいのですが、どういう風にプログラムをくめばいいか分かりません
変数宣言と代入式及びprintfを使ってです
viです。

10で割って余りを出して順に表示させればいいと言われたのですが、そのプログラムが分かりません;;

説明不足ですみませんが、分かる方教えてください

Aベストアンサー

基本的な文法はわかっていると思いますので
プログラムを書くならこんな感じになると思います。

#####ここから##########

0.変数の宣言
余りが入る変数
商が入る変数

1.入力を受け付ける //scanf

2.余り=入力された値%10;
3.余りを表示 //printf
4.商 = 入力された値 / 10;

5.余り=商%10;
6.余りを表示 //printf
7.商 = 商 / 10;

8.余り=商%10;
9.余りを表示 //printf
10.商 = 商 / 10;

11.余り=商%10;
12.余りを表示 //printf
13.商 = 商 / 10;


#####ここまで##########

whileを使わないでってことなので、
こんな書き方でしょうか

Qビット列を表示するプログラム

C言語の問題でビット列を表示するプログラムが全くできません。
どなたか分かる人はどうか知恵を貸してください。

ユーザが整数を入力すると、その整数をINT型の変数に入れ、そのビット列を表示するプログラム。
ただ、INT型のビット数は環境によって変わる可能性があるため、sizeof()関数を利用してINT型の変数のビット数を求め、そのビット数分だけ表示する。

Aベストアンサー

sizeof()関数は、sizeof()演算子ですね。

ループで、1ビットを論理積評価して結果を逆順に表示するのが
簡単ですが、一例として以下も参考にしてみて下さい。

<リスト>
#include <stdio.h>

int main()
{
int i; … 1
unsigned int mask=0x80<<(8*(sizeof(i)-1)); … 2

printf("数値?"); … 3
scanf("%d",&i); … 4
do printf("%1d",i&mask?1:0); while (mask>>=1); … 5
printf("\n"); … 6
return 0; … 7
}

<説明>
1.int 型の変数宣言
2.1オクテット(最小バイトビット数が8ビット)
での最上位ビットを算出する。
つまり、
1オクテット(固定8ビット)の最上位ビットの 0x80 を
(バイトサイズ - 1)× 8 回
左シフトすれば良いわけです。
※2によりビットマスクが算出できます。
3、4.整数入力
5.ビットマスクを最上位から最下位までずらしてそれぞれの
入力整数値とビットマスクの論理積が 0 であれば目的ビットは 0、
論理積が 0以外 であれば目的ビットは 1 と出力します。

たとえば、
int : 2バイト
入力整数値(10進数):32768(16進で 0xF0F0)
(2進で 11110000 11110000)の時、
ビットマスク = 0x80 を (sizeof(int) - 1) * 8 回分、左シフト
= 0x80 を(2 - 1) * 8 回分、左シフト
= 0x8000 (2進で、10000000 00000000)
1回目:11110000 11110000 & 10000000 00000000 = 10000000 00000000
… 10進数で 0 以外なので「1」を表示(表示結果:1)
ビットマスクを右にずらすので、mask = 01000000 00000000
2回目:11110000 11110000 & 01000000 00000000 = 01000000 00000000
… 10進数で 0 以外なので「1」を表示(表示結果:11)
ビットマスクを右にずらすので、mask = 00100000 00000000


16回目:11110000 11110000 & 00000000 00000001 = 00000000 00000000
… 10進数で 0 なので「0」を表示(表示結果:11110000 11110000)
ビットマスクを右にずらすので、mask = 0000000 00000000
ループはマスクが 0 になったら抜けるので終了です

sizeof()関数は、sizeof()演算子ですね。

ループで、1ビットを論理積評価して結果を逆順に表示するのが
簡単ですが、一例として以下も参考にしてみて下さい。

<リスト>
#include <stdio.h>

int main()
{
int i; … 1
unsigned int mask=0x80<<(8*(sizeof(i)-1)); … 2

printf("数値?"); … 3
scanf("%d",&i); … 4
do printf("%1d",i&mask?1:0); while (mask>>=1); … 5
printf("\n"); … 6
return 0; … 7
}

<説明>
1.int 型の変数宣言
2.1オクテット(最小バ...続きを読む

Qビット列を走査するプログラムの関数化

char型の変数に0or1を入れて擬似的にビット列にした配列をLSBからMSBまで走査し、一致したらループを抜け終了するプログラムをCで書きたいと思っています。
他のプログラムでも使いまわし、かつ見やすくするためにこの部分を関数化したいのです。ソースにはbreakを使っているのですが、当然ながらbreakはforかwhile内で使わないとダメだと思いますが、ソース作成の都合上、for文は関数内に入れたくないのです。
(つまり、条件分岐を関数化したものをfor文内で用いたい)

うまい方法が思いつかずに困っています。もし良い方法をお気づきの方がおられたらご助力下さい。

//===============================================//
//=================以下ソース====================//
//===============================================//
//ビット配列correct_ciphertextとPbinを比較するプログラム
//LSBからMSBまで順に走査を行い、違うビットが出てきた時点でbreakし、走査を止める
//Pbinは固定値を与えている
#include <stdio.h>
#include <string.h>

unsigned int mes[2];
unsigned int key[2];
char Pbin[64];
char Kbin[64];
char ciphertext[64] = { 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0};

void ConvertPtextToBin_ForHost(unsigned int mes[]){
unsigned int tmp_mes[2] = {mes[0], mes[1]};
int i, j;
for(j=0;j<=1;j++){
for(i=0;i<=31;i++){
Pbin[j*32 + 31-i] = tmp_mes[j] % 2;
tmp_mes[j] = tmp_mes[j] / 2;
}
}
}


int main(int argc, char *argv[]){
//initialize
mes[0] = 0x00000000;
mes[1] = 0x00000000;

int i, j, k;
int x=0, y=0;
while(1){
printf("mes[1] = %d\n", mes[1]);
ConvertPtextToBin_ForHost(mes);
for(i=0; i<64; i++){
printf("%d", Pbin[i]);
if((i+1)%8 == 0)
printf(" ");
}
printf("\n");

//*************************
//ビット走査
//*************************
for(k=0; k<64; k++){
if( (ciphertext[63-k] == Pbin[63-k]) ){
//同じビットであれば、次のビットを走査する
}else{
printf("Error\n");//後ろから走査していって、1ビットでも違うものがあれば違うビット列と判断する
break;
}
}
//ここに来たら違うビット列だったということ
if(k != 64){
mes[1]++;
printf("Not match ciphertext... %dth bit didn't match. (0bit:LSB)\n", k);
printf("This was %d*%dth Search...\n\n", y, x);
x++;
if(x>=65535){i=0; y++;}
}else{
//k=64つまり、最後のビットまで同じビットだったということ⇒つまり、「発見」
printf("Match ciphertext\n");
printf("This was %d*%dth Search...\n\n", y, x);
break;
}
//***********************
//ビット走査の終了
//***********************
}
}

char型の変数に0or1を入れて擬似的にビット列にした配列をLSBからMSBまで走査し、一致したらループを抜け終了するプログラムをCで書きたいと思っています。
他のプログラムでも使いまわし、かつ見やすくするためにこの部分を関数化したいのです。ソースにはbreakを使っているのですが、当然ながらbreakはforかwhile内で使わないとダメだと思いますが、ソース作成の都合上、for文は関数内に入れたくないのです。
(つまり、条件分岐を関数化したものをfor文内で用いたい)

うまい方法が思いつかずに困ってい...続きを読む

Aベストアンサー

こんな感じでどうでしょうか
一応動作確認はしてあります

//// ソースはここから ///////////////////////////////////////////
// ChkBit.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

//ビット配列correct_ciphertextとPbinを比較するプログラム
//LSBからMSBまで順に走査を行い、違うビットが出てきた時点でbreakし、走査を止める
//Pbinは固定値を与えている
#include <stdio.h>
#include <string.h>

// 扱う最大ビット長
#define MAX_BIT_LENGTH64
// ブロック化するビット長
#define BLOCK_LENGHT8


unsigned int mes[2];
unsigned int key[2];
char Pbin[MAX_BIT_LENGTH];
char Kbin[MAX_BIT_LENGTH];
char ciphertext[MAX_BIT_LENGTH] =
{ 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0};

// 指定された配列(bitをエミュレート)の指定ビットに値を設定する
static void SetBit(char Dest[], int Pos, int Bit)
{
Dest[Pos] = Bit;
}


static void ConvertPtextToBin_ForHost(unsigned int mes[])
{
unsigned int tmp_mes[2] = {mes[0], mes[1]};
int i, j;
for(j = 0;j <= 1;j++)
{
for(i = 0;i <= 31;i++)
{
SetBit(Pbin, j * 32 + 31 - i, tmp_mes[j] & 0x01);
tmp_mes[j] >>= 1;
}
}

}

// 8ビットを1ブロックとして区切りながら表示する
static void FmtDisp(char sec[])
{
int i;
for (i = 0; i< MAX_BIT_LENGTH; i++)
{
printf("%d", Pbin[i]);
if (!((i+1) % BLOCK_LENGHT))
printf(" ");
}
printf("\n");
}

// ビットパターン配列(char配列)を比較し
// 配列[0]がMSB 配列[MAX_BIT_LENGTH - 1]がLSBとする
// LSBから順にサーチするものとする
// 最初に違いが見つかったビットの番号(MSB = 0)を返す
// 全ビット一致した場合はLengthを戻す
static int FindDiffBitNumber(char buf1[], char buf2[], int Length)
{
int i;
for (i = 0; i < Length; i++)
{
int n;

n = Length - 1 - i;// LSBを基準としたビット位置
if (buf1[n] != buf2[n])
return i;
}

return Length;
}

// ビット走査を行う
// 違うなら0, 同一なら0以外を戻す
static int SearchBit(char buf1[], char buf2[], int Length,
unsigned int mes[], int* x, int* y)
{
long n;

n = FindDiffBitNumber(buf1, buf2, Length);
if(n < Length)
{
// 違うビットが検出された場合
mes[1]++;
printf("Not match ciphertext... %dth bit didn't match. (0bit:LSB)\n", n);
printf("This was %d*%dth Search...\n\n", *y, (*x)++);

if (*x >= 65535)
{
(*y)++;
}

return 0;
}
else
{
// 同一だった場合
printf("Match ciphertext\n");
printf("This was %d*%dth Search...\n\n", *y, *x);
return 1;
}
}


int main(int argc, char *argv[])
{
int x = 0, y = 0;


//initialize
mes[0] = 0x00000000;
mes[1] = 0x00000000;

do
{
printf("mes[1] = %d\n", mes[1]);
ConvertPtextToBin_ForHost(mes);

// 8ビットを1ブロックとして区切りながら表示する
FmtDisp(Pbin);

} while (!SearchBit(ciphertext, Pbin, MAX_BIT_LENGTH, mes, &x, &y)) ;
}

/// ソースはここまで ///////

x, yはSearchBit()関数内のstatic変数として、
パラメータから除くことも考えました。

しかし、 SearchBit()が使いまわされることを考えると、
x, yのリセット処理が必要になります。

この辺は単なる関数化だけでなく、
"モジュール化"も考えたほうがいいかとも思います。
(C++のクラス化も大いにありです)
そして
x, yはstatic変数(C++ではメンバ変数)とし、
SearchBit()のパラメータから除く。
代わりにx,yをリセットする関数を設ける
こちらのほうが使いやすいと思います。

こんな感じでどうでしょうか
一応動作確認はしてあります

//// ソースはここから ///////////////////////////////////////////
// ChkBit.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

//ビット配列correct_ciphertextとPbinを比較するプログラム
//LSBからMSBまで順に走査を行い、違うビットが出てきた時点でbreakし、走査を止める
//Pbinは固定値を与えている
#include <stdio.h>
#include <string.h>

// 扱う最大ビット長
#define MAX_BI...続きを読む

Q行列A(l行m列)と行列B(m行n列)の積C(l行n列)を求めるプログラム

ヒントを頂きたいです。
よろしくおねがいします。

Aベストアンサー

行列の積を求めるプログラムは、過去にも、何回かでてきました。
参考URLのものは、固定のサイズですけど、
mallocで動的にサイズを確保するか、
計算可能な最大の大きさをあらかじめ決めておくか
することになると思います。

参考URL:http://okweb.jp/kotaeru.php3?qid=1391489

Q4桁の英字の3桁目を当てるプログラム

乱数でとってくる4ケタの英字の3桁目を入力して当てるプログラムを
組もうとしているのですが、コンパイラしてもいまいちうまくいきません。

特に下に書いたプログラムのこの部分が違っていると思い
どのように修正したらよいのか指摘していただきたいです。
human=getchar();

if(comp[2]!=human)
{
ero=1;
}
よろしくお願いします。

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

int sleep(unsigned long x)
{
clock_t c1=clock(),c2;

do{
if((c2=clock())==(clock_t)-1)
{
return 0;
}
}while(1000.0*(c2-c1)/CLOCKS_PER_SEC<x);
return 1;
}

int main(void)
{

int num,val,i,j;
char comp[21];
char human;
int ero=0;
int try_count=0;
int seikai=0;
clock_t start,end;
int num1;
char eiji[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";

srand(time(NULL));
puts("英字記憶トレーニング");

do{
printf("挑戦するレベル(3~20):");
scanf("%d",&num1);
}while(num1<3 || num1>20);

printf("%d個の英字を記録しましょう。\n",num1);

start=clock();

do{

for(i=0;i<num1;i++)
{
comp[i]=eiji[rand()%strlen(eiji)];
}
comp[num1]='\0';

printf("%s",comp);
fflush(stdout);
sleep(125*num1);
printf("\r%*s\r3番目の英字を入力してください:",num1,"");
human=getchar();

if(comp[2]!=human)
{
ero=1;
}

if(ero==0)
{
printf("正解です。\n");
seikai++;
}
else
{
printf("\a間違いです。\n");
}
try_count++;

}while(try_count<2);

end=clock();

printf("%d回中%d回成功しました。\n",try_count,seikai);
printf("%.1f秒でした。\n",(double)(end-start)/CLOCKS_PER_SEC);

return 0;
}

乱数でとってくる4ケタの英字の3桁目を入力して当てるプログラムを
組もうとしているのですが、コンパイラしてもいまいちうまくいきません。

特に下に書いたプログラムのこの部分が違っていると思い
どのように修正したらよいのか指摘していただきたいです。
human=getchar();

if(comp[2]!=human)
{
ero=1;
}
よろしくお願いします。

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

int sleep(unsigned long x)
{
clock_t c1=clock(),c2;

do{
if((c2=clo...続きを読む

Aベストアンサー

>上記プログラムにhuman=getcharの上に下の文を入れるだけで
>動作するようになりました。
では、根本的な解決にはなってませんよ。

>「改行が入力になる」という意味がよくわからないので説明をしていただけると嬉しいです。
と関連しますが、
「リターンキー」もキーボードの入力の一つです。
そして、関数には
・リターンキーが押されるまでを取得する(リターンキーは入力バッファに残ったまま)
・「キー入力」ならなんでも取得する
という二種類が存在します。
scanf()は前者でありリターンキーはバッファに残ったままです。
次の入力関数を実行した際にその残ったリターンキーを読み込んでしまう為に起こる問題です。
No.2氏の回答は、キーバッファに残ったままのキー入力を読み飛ばす為の処理です。
(読み飛ばしはscanf( "%*[^\n]" ); の方がいいと思いますが)

ちなみに、ソース上の
>fflush(stdout);
は何を行っている化知ってますか?


人気Q&Aランキング

おすすめ情報