次のコードでは、char 配列は位置 1 と 2 で最大 100 文字を出力しますが、位置 3 では 22 文字しか出力しません。この動作の理由は何ですか?
#include<stdio.h>
/* print the longest input line */
/*Exercise 1-16. Revise the main routine of the longest-line program so it will correctly print the length of arbitrary long input lines, and as much as possible of the text.*/
#define MAXLENGTH 100
int mygetline(char s[], int limit);
void charcopy(char to[], char from[]);
int main(){
char current[MAXLENGTH];
char longest[MAXLENGTH];
int curlen;
int maxlen;
maxlen = 0;
while( (curlen = mygetline(current, MAXLENGTH)) > 0 ){
if (curlen > 80)
printf("\nvery long:%d; %s\n", curlen, current);//#1# prints 100 digits
if(curlen>maxlen){
maxlen=curlen;
charcopy(longest, current);
printf("\nlonger:%d; %s\n", maxlen, longest);//#2# prints 100 digits
}
}
if (maxlen)//char array seems to truncates itself at scope boundry.
printf("\nlongest:%d; %s\n", maxlen, longest);//#3# prints 22 digits
printf("\nall done!\n");
return 0;
}
int mygetline(char s[], int limit){
int i, c;
for(i=0; i < limit-1 && ((c=getchar()) != EOF) && c != '\n'; ++i)
s[i]=c;
if(c=='\n'){
s[i]=c;
++i;}
else
if(i >= limit-1)
while (((c=getchar()) != EOF) && c != '\n')
++i;
s[i]='\0';
return i-1;
}
void charcopy(char to[], char from[]){
int i;
i=0;
while( (to[i] = from[i]) != '\0'){
++i;}
}
コメントで 3 とマークされた場所は、100 文字ではなく 22 文字しか出力されません。非常に奇妙です。
編集: Scotts の回答に従って、mygetline を次のように変更しました。
int mygetline(char s[], int limit){
int i, c, k;
for(i=0; i < limit-1 && ((c=getchar()) != EOF) && c != '\n'; ++i)
s[i]=c;
if((c=='\n') && (i < limit -1)){
s[i]=c;
++i;}
else{//if we are over the limit, just store the num of char entered without storing chars
k = 0;
while (((c=getchar()) != EOF) && c != '\n')
++k;}
s[i]='\0';
return i+k;
}
ご覧のとおり、入力が制限を超えた場合、入力された文字の数は、配列に触れないまったく新しい変数 k に格納されます。最後に印刷された行が切り捨てられ、行の長さとして奇妙な 32770 が表示されます。なぜですか? ご覧のとおり、アレイはベビーシッターで甘やかされ、正確な量のイワナだけを与えられ、それ以上は与えられていません。
編集:最初のリストの問題は、スコットが指摘したように、配列をオーバーシュートしていたことです。2 番目の mygetline の問題はk=0;
、if else ネストの内部で初期化されていたことです。初期化を上に移動し、関数全体に対してグローバルにすることで、2 番目の問題が解決されるようです。
次のように mygetline を使用します。
int mygetline(char s[], int limit){
int i, c, k;
k=0;
for(i=0; i < limit-1 && ((c=getchar()) != EOF) && c != '\n'; ++i)
s[i]=c;
if((c=='\n') && (i < limit -1)){
s[i]=c;
++i;}
else{//if we are over the limit, just add the num of char entered without storing chars
while (((c=getchar()) != EOF) && c != '\n')
++k;}
s[i]='\0';
return i+k;
}