2016-04-16 11 views
0

scanf()は前の '\ n'を読み込んでいるようです。私は連結された文字列を1行で取得しようとしています。 2番目の文字列の先頭に '\ n'を取り除くにはどうしたらいいですか?改行の削除は非常に難しい

これはCプログラムです。

私は、次の行が読み込まれる前にバッファを何とかフラッシュしなければならないと推測していますが、エラーなしでこれを行う方法はわかりません。

Btw、ここではcin.get()や他の標準的なcin/cout操作は使用できません。私は標準の文字列演算を使用することはできません。なぜなら、私は文字列ではなく、c-stringとstrings.hで排他的に作業しているからです。標準入力から

入力は次のとおりです。

12 4.0 Spot run!

int main() { 
    int i = 4; 
    double d = 4.0; 
    char s[] = "See "; 

    int isum; 
    int MAX_SIZE = 256; 
    double dsum; 
    char s2[MAX_SIZE]; 

    scanf("%i",&isum); 
    scanf("%lf",&dsum); // Hope to clear out the newline from reading 
         // in the double value. Or any other newline 
         // before the next scarf(), but haven't figured 
         // how. 
    scanf("%79c", s2); 

    isum += i; 
    printf("%d \n",isum); 

    dsum += d; 
    printf("%.1f \n",dsum); 

    char newchar[MAX_SIZE]; 
    strcpy(newchar,s); 
    newchar[strcspn(newchar,"\n")]='\0'; 
    s2[strcspn(s2,"\n")] = 't'; //To test where newline is in second string. 
    strcat(newchar,s2); 
    printf("%s",newchar); 

    return 0; 

私の出力は、次のとおりです。スポットの前に 'T' --note

16 8.0 See tSpot run! // <!

+1

C++を勉強していますか?これはCプログラムのようです。 –

+0

あなたが正しいです、私は正しいことを行います。私はまだCスタイルの習慣を使用している古いCプログラマーの束からC++を学んだので、すぐにそれを選んだわけではありません。私はタグを修正します。 – NonCreature0714

+0

"* scanf()は以前の '\ n'を読み込んでいるようです。*"それは驚くべきことでしたか?もしそうなら、あなたはそれを何と読もうと思いましたか? –

答えて

2

要求通りです。

scanf()とその親類の動作に関する多くの疑問があります。これは、標準Cライブラリの中でもっとも微妙で複雑な機能のいくつかです。 %lfのような変換仕様では、次の文字が数字の一部でないときは読み込みを停止します。その文字は次の変換仕様で処理されます。 %c%[…]スキャンセットおよび%nと一緒に)は、先頭の空白をスキップしません。他のすべての変換仕様は、先頭の空白をスキップします。改行を数値入力に残さない場合は、" %79c"を使用して空白をスキップしてください。書式文字列内の空白は、空白、タブ、および改行を含む0個以上の空白文字をスキップします。

"%79c"は、4.0の後ろから改行を読み取り、その後に改行を含む 'Spot run!'の文字を読み込み、入力がEOFに達したと仮定して読み込みを停止します。

Seeの後に改行を入れないでください。 ts2[strcspn(s2,"\n")] = 't';で、s2の最初のバイト(4.0以降の改行)を上書きします。

あなたがラインことを実現しました:

newchar[strcspn(newchar, "\n")] = '\0'; 

は何もしませんNULLバイト、とSee後のスペースの後にヌル・バイトを上書きします。

頻繁に使用する手法は、適切な括弧で囲まれた入力日付を印刷することです。時には<<…>>、時には[…]となります。たとえば:

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

int main(void) 
{ 
    int i = 4; 
    double d = 4.0; 
    char s[] = "See "; 

    int isum; 
    int MAX_SIZE = 256; 
    double dsum; 
    char s2[MAX_SIZE] = ""; // See comments. 

    scanf("%i", &isum); 
    scanf("%lf", &dsum); 
    scanf("%79c", s2); 

    printf("s2 = [%s]\n", s2); 

    isum += i; 
    printf("%d\n", isum); 

    dsum += d; 
    printf("%.1f\n", dsum); 

    char newchar[MAX_SIZE]; 
    strcpy(newchar, s); 
    newchar[strcspn(newchar, "\n")]='\0'; 
    s2[strcspn(s2, "\n")] = 't'; 
    strcat(newchar, s2); 
    printf("%s", newchar); 

    return 0; 
} 

は彼のcommentCool Guyで指摘したように、%cは(それが唯一のストレージの単一の文字を必要とする)NULLバイトを追加していないことを覚えておくことが重要です。同様に、%79cは最後にヌルバイトを追加しません。そのため、newcharに連結すると、未定義の動作を防ぐために、s2を 'すべてのバイト0'に初期化する必要があります。または、%n(2回使用される可能性があります)の巧妙なテクニックを使用して、s2に読み込まれたバイト数を調べる必要があります。そのため、イベント後にnullを終了することができます。

この変動からの出力は次のとおりです。

s2 = [ 
Spot run! 
] 
16 
8.0 
See tSpot run! 

ので、入力後の開始時とs2の最後に改行があります。

+1

'printf(" s2 = [%s] \ n "、s2);' U2は 's2'がNULで終了していないので? –

+0

@CoolGuy: 's2'は'%79c'がnullを終了しない限り、nullで終了します。私は '%c'をカウントすることはめったにありませんので、マニュアルを見てみましょう。 _ [... time passes ...] _ POSIXは、部分的には:_ヌルバイトが追加されていません。_そうです。私はヌルで終了しないことに関するコメントをいくつか持っていましたが、それは間違っていたので、それを削除しました。 '%79c'もヌル終了しないことを認識しませんでした。修正は簡単です: 'char s2 [MAX_SIZE] =" ";'配列をすべてゼロバイトに初期化する。私はコードを修正しました - ありがとう。 –

関連する問題