C言語関係掲示板

過去ログ

No.1099 入力値による配列の値が変更されるエラー

[戻る] [ホームページ]
No.14490

入力値による配列の値が変更されるエラー
投稿者---Q(2004/06/06 10:56:07)


charsetの格納されている値が、入力値により変更されます。
なぜでしょうか?
(正常な場合の入力値例)コピー&ペーストを行ってください
#include <stdio.h>
#define BUFSIZE 128

size_t str_cspn(const char *str, const char *charset);

(異常が発生する入力値例)
#include <stdio.h>
#define BUFSIZE 128

size_t str_cspn(const char *str, const char *charset);
size_t str_spn(const char *str, const char *charset);

(ソース)
#include <stdio.h>
#define BUFSIZE 128

size_t str_cspn(const char *str, const char *charset);
size_t str_spn(const char *str, const char *charset);

void main(void)
{
    char str[BUFSIZE];
    char charset[] = " #<>\t\n{}/*\"\\;()";
    char *p;
    
    int n, c;
    int i;
    
    /*ソースプログラムを配列に入力する*/
    p = str;
    while((c = getchar()) != EOF){
        *p++ = c;
    }
    *p = '\0';
    printf("\n");
    /*ソースプログラムを単語に分割する*/
    p = str;
    
    for(i = 0; charset[i] != '\0'; i++){
        
        printf("charset = %c\n", charset[i]);
        
    }
    
     while(1){
        n = str_spn(p, charset);
        p += n;
        n = str_cspn(p, charset);
        
        if(n > 0){//charsetに含まれる文字がstrに連続で2文字以上続く場合、改行するのを防ぐ
            printf("%.*s\n", n, p);
        }
        exit();
        p += n;
        if(*p == '\0'){
            printf("処理終了");
            break;
        }
    }
}

size_t str_cspn(const char *str, const char *charset)
{
    size_t len = 0;
    const char *stc = charset;

    while(*str){
        printf("1 cspn : *str = %c ⇔ %c : *charset\n", *str, *charset);
        while(*str != *charset && *charset != '\0'){
            charset++;
            //printf("2 cspn : *str = %c ⇔ %c = *charset\n", *str, *charset);
            
        }
        printf("3 cspn : *str = %c ⇔ %c = *charset\n", *str, *charset);
        if(*str == *charset){
            //printf("\n1cspn:len = %d\n", len);
            return len;
        }
        charset = stc;
        len++;
        str++;
    }
    
    printf("\ncspn : len = %d\n", len);
    return len;
}
 
   
size_t str_spn(const char *str, const char *charset)
{
    size_t  len;
    
    for(len = 0; *charset; charset++){
        printf("spn : *str : %c ⇔ %c : *charset\n", *str, *charset);
        if(*str == *charset){
            while(*str == *charset && *str != '\0'){
                str++;
                len++;
           }
           printf("\n1 spn : len = %d\n", len);
           return len;
        }
    }   
    printf("\n2 spn : len = %d\n", len);
    return len;
}





No.14492

Re:入力値による配列の値が変更されるエラー
投稿者---かずま(2004/06/06 11:26:31)


> charsetの格納されている値が、入力値により変更されます。
> なぜでしょうか?

「異常が発生する入力値例」は、約154バイトあります。
ソースプログラム中の char str[128]; に読み込もうとして
他の領域を破壊しているのでしょう。


No.14493

Re:入力値による配列の値が変更されるエラー
投稿者---かずま(2004/06/06 11:54:12)


次のようにすれば、入力のサイズの制限はかなり改善されるでしょう。

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

int main(void)
{
    char buf[1024], *p, charset[] = " #<>\t\n{}/*\"\\;()";
    int n;

    while (fgets(buf, sizeof buf, stdin))
        for (p = buf; *p; p += n) {
            n = strspn(p, charset);
            p += n;
            n = strcspn(p, charset);
            if (n == 0) break;
            printf("%.*s\n", n, p);
        }
    return 0;
}

----------------------------------------------------------------------
上のプログラムでは、標準関数 strspn, strcspn を使っていますが、
これを自前で用意するとすれば、

size_t str_spn(const char *str, const char *charset)
{
    const char *p, *q;

    for (p = str; *p; p++)
        for (q = charset; *p != *q; q++)
            if (!*q) return p - str;
    return p - str;
}

size_t str_cspn(const char *str, const char *charset)
{
    const char *p, *q;

    for (p = str; *p; p++)
        for (q = charset; *q; q++)
            if (*p == *q) return p - str;
    return p - str;
}