2017-04-11 4 views
0

UNIXシステムコマンドの使用に関する練習をしていますが、開始文字から2つのファイルを読み込もうとしています。文字が異なる場合、プログラムは両方のファイルの残りの文字と文字が異なる位置に印刷されるはずです。初期化された文字配列が同じメモリを指しています

Ex。 ex1.txtには「My name is Carl」、ex2.txtには「My name is John」があります。 ex1の場合は「Carl」、ex2の場合は「John」が印刷されます。

私のプログラムは読み込みと位置情報を行いますが、読み込みバッファを初期化して比較する際に問題があります。

2つのサイズのchar配列を初期化していますが、readメソッド変数buf2を使用すると、両方のファイル文字が現在の位置に取得されます。これは、bufbuf2が同じメモリを指し示すことを意味します。私は、私のchar配列のために動的にメモリを割り当てる必要がありますか、これを行うための他の方法がありますか?

Moreso:サイズが1の場合、buf2にはどのように2文字が含まれますか?入力の

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <string.h> 

#define B_SIZE 1 

void err_exit(char *msg) { 
    perror(msg); 
    exit(EXIT_FAILURE); 
} 

int main (int argc, char** argv) { 
int file, file2, size, size2; 
char buf[B_SIZE], buf2[B_SIZE]; 
off_t pos, pos2; 

if (argc != 3) err_exit("Enter two files as arguments"); 
if ((file = open(argv[1], O_RDONLY)) == -1) err_exit("Cant open file 1"); 
if ((file2 = open(argv[2], O_RDONLY)) == -1) err_exit("Cant open file 2"); 

size = lseek(file, B_SIZE, SEEK_END); 
size2 = lseek(file2, B_SIZE, SEEK_END); 
pos = lseek(file, 0, SEEK_SET); 
pos2 = lseek(file2, 0, SEEK_SET); 

printf("\n\nPOS: %d, %d SIZE: %d, %d\n", pos, pos2, size, size2); 
pread(file, &buf, B_SIZE, pos); 
pread(file2, &buf2, B_SIZE, pos2); 

while(((pos = lseek(file, B_SIZE, SEEK_CUR)) < size) 
&& ((pos2 = lseek(file2, B_SIZE, SEEK_CUR)) < size2)) 
{ 
    printf("Searching first different char: POS: %d\nChar: %s, %s\n", pos, buf, buf2); 
    printf("Is buf same as buf2: %d\n", (strcmp(buf, buf2))); 
    pread(file, &buf, B_SIZE, pos); 
    pread(file2, &buf2, B_SIZE, pos2); 

} 

if ((size == size2) && (pos == pos2)){ 
    printf("Files are the same\n"); 
} else { 
    printf("\nNot same anymore. POS: %d\n", pos); 
    printf("Print file 1 starting from this position\n"); 
    while(((pos = lseek(file, B_SIZE, SEEK_CUR)) < size)){ 
     pread(file, &buf, B_SIZE, pos); 
     printf("%s", buf); 
    } 
    printf("\n\nPrint file 2 starting from this position\n"); 
    while(((pos2 = lseek(file2, B_SIZE, SEEK_CUR)) < size2)){ 
     pread(file2, &buf, B_SIZE, pos2); 
     printf("%s", buf); 
    } 
} 




close(file); 
close(file2); 
return 0; 
} 

例:
Output of program

+1

Cは境界チェックがありません。境界から外れると*未定義の動作につながります*。 –

+1

バッファのサイズは1文字です。それは空の文字列( ''\ 0'')とそれ以外の文字列の 'strcmp'のみを保持することはできません(そのサイズのバッファに他の文字列はありません)。 –

答えて

1

あなたは、文字列の概念に違反しています。 例:

strcmp(buf, buf2) 

文字列ゼロ終端でなければなりません。文字列が必要な関数にchar*を渡す場合、でなければなりません。ゼロ終了文字列を指していることを確認してください。

バッファのサイズは1にすぎないので、ゼロ終了の余地はありません。したがって、不正な関数呼び出しを行い、未定義の動作をします。

あなたはこの試みることができる:

char buf[B_SIZE+1], buf2[B_SIZE+1]; 
buf[B_SIZE] = '\0'; 
buf2[B_SIZE] = '\0'; 

をしかし、あなたはchar型の変数に読み込まれない理由を文字ごとに文字を読みたい場合。文字は、==を使用して比較することができます。これは、より速く簡単です。strcmp

関連する問題