スティック。他の人が指摘したように
、でもlen1
とlen2
が間違っている設定する際sizeof
を使用して、fgets
正しいの内部sizeof
を行い、その変更、で、代わりにchar *input1 = malloc(...)
のchar input1[100]
を使用しかし。有効な文字が10文字であっても(残りの文字は未定義/ランダム)、の全体のバッファを100に処理します。
実際に有効な長さを得るには、strlen
と改行が必要です。
ここで変更されたコードは、[無償スタイルのクリーンアップをご容赦ください]です。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
min(int a, int b, int c)
{
if (a > b && a > c)
return a;
if (b > a && b > c)
return b;
return c;
}
int
main(void)
{
// allocate size for strings
int i;
int j;
char input1[100];
char input2[100];
// ask for input
printf("Enter the first string: ");
fgets(input1, sizeof(input1), stdin);
int len1 = strlen(input1);
if (input1[len1 - 1] == '\n') {
input1[len1 - 1] = 0;
--len1;
}
printf("\nEnter the second string: ");
fgets(input2, sizeof(input2), stdin);
int len2 = strlen(input2);
if (input2[len2 - 1] == '\n') {
input2[len2 - 1] = 0;
--len2;
}
// make matrix
int c[len1 + 1][len2 + 1];
// set up input 2 length
for (i = 0; i < len2 + 1; i++) {
c[0][i] = i;
}
// set up input 1 length
for (i = 0; i < len1 + 1; i++) {
c[i][0] = i;
}
// fill in the rest of the matrix
for (i = 1; i < len1; i++) {
for (j = 1; j < len2; j++) {
// if the 1st letters are equal make the diagonal equal to the last
if (input1[i] == input2[j])
c[i][j] = c[i - 1][j - 1];
else
c[i][j] = 1 + min(c[i - 1][j - 1], c[i - 1][j], c[i][j - 1]);
}
}
// print the matrix
printf("\n");
for (j = 0; j < len2; j++) {
for (i = 0; i < len1; i++) {
printf("| %d", c[i][j]);
}
printf("\n");
}
return 1;
}
UPDATE:私はあなたが何を意味するか見
オーケー甘いです!私がmallocを使用しようとしていた理由は、100x100の空白のサイズを印刷しなければならない行列を作らないようにするためでした。固定サイズinput1
又はmalloc
EDどれかで
、fgets
のみ入力サイズにそれを充填するには、[必要に応じて、第二引数にクリップ】入力されました。しかし、ではなく、は、バッファの残りの部分をのいずれかで埋め込みます.(たとえば、右側のスペース)。内容 doは、入力から読み込まれた最後のcharの後のEOS [end-of-string]文字[バイナリ0x00]を追加します[通常は改行です]。したがって
、入力文字列がある場合:abcdef\n
、[strlen
から得られる]の長さは7であり、入力が[7] 0x00であろう、そしてinput1[99]
スルーinput1[8]
は不定/ランダム/予測不可能な値とないスペースを有することになります。
改行文字は非常に有用ではないので、後で処理する前に切り捨てられることがよくあります。たとえば、小さなフレーズの編集距離を計算するときはあまり関係ありません。
strlen()を使用すると、配列内の文字数がカウントされるだけですか、それともすべての空白も含まれますか?
私は前述したように、fgets
は最後でないパッドの文字列をして、そう、心配することはありません。それはあなたが望む/期待することをするでしょう。
strlen
は、[ではなく、EOSターミネータ文字(すなわちゼロ)を含むまでの文字列をカウントします。これらの文字の一部が空白になる場合、はでカウントされます。これは私たちが望むものです。
は、以下フレーズのいずれか2つの間の編集距離計算検討:各場合において
quick brown fox jumped over the lazy dogs
the quick brown fox jumped over lazy dogs
quick brown fox jumps over the lazy dog
を、我々はstrlen
の長さの計算に[内部/埋め込み]スペースを含める。 はなので、フレーズの編集距離を計算するのに完全に有効です。
malloc
のための有効な使い方があります:データの量がスタックに収まるように大きすぎるとき。ほとんどのシステムにはデフォルトの制限があります(例えば、Linuxでは8 MBです)。
たちは、[ファイルから読み込む] 2つの章のための編集距離を計算して、我々は(例えば)を持っているだろうと仮定します。
char input1[50000];
char input2[50000];
上記収まるだろうが、c
マトリックスは、スタックオーバーフローを引き起こします:
int c[50000][50000];
50000 * 50000 * 4
(約9.3 GB)です。
したがって、このすべてのデータを収めるには、ヒープにデータを割り当てる必要があります。 をc
とにすることは可能ですが、2D行列アクセスを維持するには、関数を作成してc
へのポインタを渡す必要があります。
だから、ここ任意の大きなサイズの入力を受け取り修正版です:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#define sysfault(_fmt...) \
do { \
fprintf(stderr,_fmt); \
exit(1); \
} while (0)
#define C(y,x) c[((y) * (len2 + 1)) + (x)]
long
min(long a, long b, long c)
{
if (a > b && a > c)
return a;
if (b > a && b > c)
return b;
return c;
}
char *
input(const char *prompt,long *lenp,const char *file)
{
FILE *fp;
char *lhs;
int chr;
long siz;
long len;
if (file != NULL)
fp = fopen(file,"r");
else {
fp = stdin;
printf("Enter %s string: ",prompt);
fflush(stdout);
}
lhs = NULL;
siz = 0;
len = 0;
while (1) {
chr = fgetc(fp);
if (chr == EOF)
break;
if ((chr == '\n') && (file == NULL))
break;
// grow the character array
if ((len + 1) >= siz) {
siz += 100;
lhs = realloc(lhs,siz);
if (lhs == NULL)
sysfault("input: realloc failure -- %s\n",strerror(errno));
}
lhs[len] = chr;
len += 1;
}
if (file != NULL)
fclose(fp);
if (lhs == NULL)
sysfault("input: premature EOF\n");
// add the EOS
lhs[len] = 0;
// return the length to the caller
*lenp = len;
return lhs;
}
int
main(int argc,char **argv)
{
long i;
long j;
char *input1;
long len1;
char *input2;
long len2;
long *c;
--argc;
++argv;
switch (argc) {
case 2:
input1 = input("first",&len1,argv[0]);
input2 = input("second",&len2,argv[1]);
break;
default:
input1 = input("first",&len1,NULL);
input2 = input("second",&len2,NULL);
break;
}
// make matrix
c = malloc(sizeof(*c) * (len1 + 1) * (len2 + 1));
if (c == NULL)
sysfault("main: malloc failure -- %s\n",strerror(errno));
// set up input 2 length
for (i = 0; i < len2 + 1; i++) {
C(0,i) = i;
}
// set up input 1 length
for (i = 0; i < len1 + 1; i++) {
C(i,0) = i;
}
// fill in the rest of the matrix
for (i = 1; i < len1; i++) {
for (j = 1; j < len2; j++) {
// if the 1st letters are equal make the diagonal equal to the last
if (input1[i] == input2[j])
C(i,j) = C(i - 1,j - 1);
else
C(i,j) = 1 + min(C(i - 1,j - 1), C(i - 1,j), C(i,j - 1));
}
}
// print the matrix
printf("\n");
for (j = 0; j < len2; j++) {
for (i = 0; i < len1; i++) {
printf("| %ld", C(i,j));
}
printf("\n");
}
return 1;
}
「\ n」はウル第二のfgetsは、2行目をつかむことができない理由は、まだバッファに残っている、つまり入力の。 – Mox
代わりにchar1 [100]を使ってみましたか? – brijs
sizeof(input1)の使用が間違っていると、u100が返されず、代わりにuaのサイズが1になります。 – Mox