配列の中の特定の文字を削除して詰めるには

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

配列の中の特定の文字を削除して詰めるには

#1

投稿記事 by lily » 6年前

コード:

  for (i=0;i<300;i++){
        if (array[i]>=97&&array[i]<=122){
        array[i]=array[i]-32;
        }
        else if (array[i]>=65&&array[i]<=90){
            array[i]=array[i];
        }
        else{
            array[i]=array[i+1];   
        }      
    }
配列に格納された文字列をアルファベットの小文字なら大文字にして、それ以外の空白やカンマなどは削除して詰めるプログラムを書きたいのですが、これで上手くいきません。
詰めるというのは配列の要素に一つ隣の要素を代入するではダメなのでしょうか?

box
記事: 2002
登録日時: 13年前

Re: 配列の中の特定の文字を削除して詰めるには

#2

投稿記事 by box » 6年前

lily さんが書きました: 上手くいきません。
これだけでは何とも…。
どのようにうまくいかないのでしょうか。うまくいかないコード全体と入力データ、出力データの例を示してください。
lily さんが書きました: 詰めるというのは配列の要素に一つ隣の要素を代入するではダメなのでしょうか?
たぶんダメでしょうね。空きができた箇所から後ろのデータを「すべて」1個前へ詰めないと…。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

box
記事: 2002
登録日時: 13年前

Re: 配列の中の特定の文字を削除して詰めるには

#3

投稿記事 by box » 6年前

例えば、要素数が10で[3]が空いたとしましょうか。このときは、
[4]~[9]を[3]~[8]へ移して、[9]には'\0'(文字列終端の印)を入れるという
操作が必要なはずです。
この処理を行なうための関数(引数は、例えば詰める部分の始めと終わり)を準備しておくとよいかもしれません。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

lily

Re: 配列の中の特定の文字を削除して詰めるには

#4

投稿記事 by lily » 6年前

コード:

int i;
char array[10]={A,B,C,!,D,E,F,G,H,I};

   for (i=0;i<10;i++){
     if (array[i]==!){
       while (array[i]<10){
        array[i]=array[i+1];
        i++;
        }
       }
                   }
ありがとうございます。
これで!の箇所が削除されて詰められるでしょうか?
これでも上手く動きません。

かずま

Re: 配列の中の特定の文字を削除して詰めるには

#5

投稿記事 by かずま » 6年前

lily さんが書きました: これでも上手く動きません。
main を含むコードを書いてください。
コンパイラのエラーメッセージは何ですか?

lily

Re: 配列の中の特定の文字を削除して詰めるには

#6

投稿記事 by lily » 6年前

コード:


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

void processFile(char *array, int *size);
void cipher(char *array, int size);
void outputCode(char *array, int size);

FILE *fpIn,*fpOut;

int main(void){
    
    char array[300];
    int size=0;
    
    fpOut=fopen("csis.txt","w");
    
    
    processFile(array,&size);
    cipher(array,size);
    outputCode(array,size);
    
    fclose(fpOut);
    return 0;
    
}
void processFile(char *array,int *size){
    
    int i,k=0;
    if (!(fpIn=fopen("congress.txt","r"))){
        printf("congress.txt could not be opened.");
    }
    
        fgets(array,300,fpIn);
   
    
    for (i=0;i<300;i++){
        if (array[i]>=97&&array[i]<=122){
        array[i]=array[i]-32;
        }
        else if (array[i]>=65&&array[i]<=90){
            array[i]=array[i];
        }
        else{k=i;
            for (i=i;i<300;i++){
                array[i]=array[i+1];
            }i=k;
           
        }
    }
    *size=strlen(array);
}
void cipher(char *array, int size){
    int i,k=1;
    
    for (i=0;i<size;i++){
        if ((array[i]+k)>90){
            array[i]=array[i]+k-26;
        }
        else{
            array[i]=array[i]+k;
        }
    }
}
void outputCode(char *array, int size){
    int i;
    
    for (i=0;i<size;i++){
        if (i%5==0&&i!=0&&i%50!=0){
            printf(" %c",array[i]);
        }else if (i%50==0&&i!=0){
            printf("\n%c",array[i]);
        }else{
            printf("%c",array[i]);
        }
    }
    printf("\n");
}

ファイルから読み込んだ文字列をアルファベットの小文字は大文字にして、それ以外は削除してさらにそれを1つシフトさせた文字列を出力するプログラムです。
エラーは出ていないのですが、出力が合ってません。
アルファベット以外の文字があった箇所からの出力がTのはずなのにZが出てきたりしています。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 配列の中の特定の文字を削除して詰めるには

#7

投稿記事 by みけCAT » 6年前

processFile関数において、終端のナル文字も削除対象にしてしまっているのがまずいですね。
さらにその削除処理において、範囲外のarray[300]を読み込み、未定義動作になっていますね。
また、ファイルの最初の行(改行文字を含む)が299バイト未満の場合、未初期化の自動変数の値(不定)を計算に使用し、未定義動作になります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: 配列の中の特定の文字を削除して詰めるには

#8

投稿記事 by かずま » 6年前

コード:

void processFile(char *array, int *size)
{
    int i, k = 0;

    fpIn = fopen("congress.txt", "r");
    if (!fpIn) {
        puts("congress.txt could not be opened."); *size = 0; return;
    }
    if (fgets(array, 300, fpIn) == NULL) {
        puts("no data"); *size = 0; return;
    }

    for (i = 0; array[i] != '\0'; i++)
        if (array[i] >= 'a' && array[i] <= 'z')
            array[k++] = array[i] - ('a' - 'A');
        else if (array[i] >= 'A' && array[i] <= 'Z') 
            array[k++] = array[i];

    array[k] = '\0';
    *size = k;
}
理解できますか?
理解せずにコピペして実行したらうまくいったでは無意味です。
理解できないときは、どんどん質問しましょう。

かずま

Re: 配列の中の特定の文字を削除して詰めるには

#9

投稿記事 by かずま » 6年前

別解

コード:

#include <ctype.h>  // isalpha, toupper

    int i = 0, k = 0;
    unsigned char c;
    while ((c = array[i++]) != '\0')
        if (isalpha(c)) array[k++] = toupper(c);
    array[k] = '\0';

lily

Re: 配列の中の特定の文字を削除して詰めるには

#10

投稿記事 by lily » 6年前

やっと理解することが出来ました。
皆さんありがとうございました!

返信

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