0

データ ファイルを取得し、1 行あたりの文字数が一定量になるように書式設定する単語書式設定プログラムを作成しようとしています。ファイルの各行の単語をループしようとすると、セグメンテーション違反エラーが発生します。

int readFile(  )
{
    int rc = 1;
    char readBuffer[ 256 ];
    char writeLine[ 256 ];
    char *word = malloc( numChars * sizeof( char ) );
    
    writeFile = fopen( writeName, "a" );
    
    if ( ( openFile = fopen( readName, "r" ) ) == NULL ) 
    {
        printf( "Unable to open %s file for read\n", readName );
        rc = 0;
    } 
    else 
    {       
        while( fgets( readBuffer, sizeof( readBuffer ), openFile) != NULL ) 
        {
            strncpy( writeLine, "", 0 );
            if ( readBuffer[0] != EOF ) 
            {
                strncpy( word, strtok( readBuffer, " " ), numChars -1 );
                while( word != NULL )
                {
                    if( strlen( word ) + strlen( writeLine ) < numChars )
                    {   
                        strcat( writeLine, word );

ここでエラーが発生します:

                        strncpy( word, strtok( NULL, " " ), numChars -1 );
                    }
                    else
                    {
                        fprintf( writeFile, "%s", writeLine );
                        strcpy( writeLine, word );
                        strncpy( word, strtok( NULL, " " ), numChars -1 );
                    }
                }
            }
        }
    }
    
    return rc;
}

なぜこれが起こっているのかわかりません。コピーする文字数を正確に伝えることがstrncpyのポイントではありませんか?文字列の長さの 1 つ下まで文字をコピーするように具体的に指示した場合、なぜセグメンテーション違反が発生するのでしょうか? 編集:コードを次のように修正しました。

            strcpy( writeLine, strtok( readBuffer, " " ) );
            
            while( strcpy( word, strtok( NULL, " " ) ) != NULL )
            {
                if( strlen( word ) + strlen( writeLine ) < numChars )
                {   
                    strcat( writeLine, word );
                }
                else
                {
                    fprintf( writeFile, "%s", writeLine );
                    strcpy( writeLine, word );
                }
            }

これは操作に変更を与えません。これは依然としてセグメンテーション違反です。トークンが有効であることを確認し、有効な場合は同じトークンにアクセスするにはどうすればよいですか?


解決済み

機能するソリューションを開発しました:

    writeLine[0] = '\0';
    
    while( fgets( readBuffer, sizeof( readBuffer ), openFile) != NULL ) 
    {
        if ( readBuffer[0] != EOF ) 
        {               
            for( word = readBuffer; NULL != ( word = strtok( word, " \t\n" ) ); word=NULL )
            {
                printf("%s\n", writeLine );
                if( strlen( word ) + strlen( writeLine ) < numChars )
                {   
                    strcat( writeLine, word );
                    strcat( writeLine, " " );
                }
                else
                {
                    printf("%s", "print\n");
                    fprintf( writeFile, "%s\n", writeLine );
                    strcpy( writeLine, word );
                    strcat( writeLine, " " );
                }
            }
        }
    }
    fprintf( writeFile, "%s\n", writeLine );
4

2 に答える 2

1

コピーする文字数を正確に伝えることがstrncpyのポイントではありませんか?

番号。ポイントは、利用可能なバッファの大きさを伝えることです。次に、可能な限り多くの文字をそのバッファーにコピーし (残りをゼロにします)、少なくともバッファー サイズと同じ数の文字が使用可能である場合は null で終了しません。

個人的には決して使用しません。実際には常に文字列を生成する代替手段にはstrcpysprintf、 、snprintf、またはmemcpynull ターミネータを手動で追加することが含まれます。

標準関数のドキュメントを読むことは常に推奨されます。strncpy( writeline, "", 0 );何もしません。

于 2014-04-25T04:29:20.603 に答える
1

strncpy()制限内の文字数に達した場合、null は終了しません。自分自身を null で終了する必要があります。これにより、ステートメントstrncpy( writeline, "", 0 );は何もしなくなります (文字列を終了することさえありません)。次に、その初期化されていない文字列に追加すると、うまくいきません。

于 2014-04-25T04:24:31.300 に答える