2017-01-24 9 views
1

は、次のプログラムを考えてみましょう:strncat():対象の文字列のランダムな文字

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

int main() { 

    int ret = 0; 

    char dirname[] = "test/"; 
    int path_maxlen = 256; 
    char path[path_maxlen]; 
    int filename_maxlen = path_maxlen - strlen(dirname); 

    strncat(path, dirname, path_maxlen - 1); 

    strncat(path, "file.txt", filename_maxlen); 

    FILE *file = fopen(path, "r"); 

    printf("path: %s\n", path); 

    if (file != NULL) { 
     printf("success\n"); 

     fclose(file); 
    } else { 
     printf("fail\n"); 
     ret = 1; 
    } 

    return ret; 
} 

これが最初で動作するように見えますが、それはそれは存在していたが、つまりは、ファイルを開くことができませんでした、失敗し始め、プログラムやファイルに変更はありませんでした。

その時点で、pathという行が追加されました。出力をファイルにリダイレクトした後、pathの前にランダムな文字(ASCII:1 SOH 'heading start')が付いていたことが判明しました。だからここではstrncatが正しく使用されておらず、いくつかのランダムな迷惑メールが私のパス配列に書き込まれると仮定します。

上記の例の文字列を正しく連結するにはどうすればよいですか?

PS:私のOSはUbuntu 16.04です。コンパイラは、次のとおりです。

$ gcc --version 
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 
+2

'char path [path_maxlen] = {0};' – DyZ

+0

@DYZ Alasは、可変長配列に対しては機能しません。 – AlexD

+0

@AlexDだから私は決して可変長配列を使用しません...だから、 'path [0] = 0;'です。 – DyZ

答えて

4
strncat(path, dirname, path_maxlen - 1); 

pathは初期化されていないので、それは未定義の動作です。

char path[path_maxlen]; 
path[0] = 0; // since path is VLA, usual "={0}" initialization does not work 

それとも、単にstrcpy_sの使用を検討することができますしてみてください。

+0

ありがとう、私は今それを参照してください。 'char path [path_maxlen] = NULL;'は動作するのでしょうか、そのアプローチには何か警告がありますか? – nautical

+0

うーん...コンパイルしますか:-)? – AlexD

+0

私は誤ってプログラムのバックアップファイルを編集してコンパイルしましたが、編集されていないファイルをコンパイルしました。だから変更はうまくいくようでした:-)。しかし、私のエラーに気づいた後、私は正しいファイルを編集し、 '{0}'も 'NULL'もコンパイルしませんでした。 – nautical

関連する問題