web-dev-qa-db-ja.com

Cを使用してキーボードから文字列を読み取る方法は?

ユーザーが入力した文字列を読みたい。文字列の長さがわかりません。 Cには文字列がないため、ポインターを宣言しました。

char * Word;

scanfを使用して、キーボードから入力を読み取りました。

scanf("%s" , Word) ;

しかし、セグメンテーション違反が発生しました。

長さが不明な場合、Cのキーボードから入力を読み取るにはどうすればよいですか?

48
mainajaved

Wordに割り当てられたストレージがありません-それは単なる ダングリングポインター です。

変化する:

char * Word;

に:

char Word[256];

ここで、256は任意の選択です。このバッファのサイズは、発生する可能性がある最大の文字列よりも大きくする必要があります。

また、 fgets は、任意の長さの文字列を読み取るための scanf よりも優れた(より安全な)オプションであり、size引数を取るため、バッファオーバーフローを防止します。

 fgets(Word, sizeof(Word), stdin);
53
Paul R

ここでscanf()を使用することが推奨されている理由がわかりません。 scanf()は、%64sなどの制限パラメーターをフォーマット文字列に追加する場合にのみ安全です。

より良い方法は、char * fgets ( char * str, int num, FILE * stream );を使用することです。

int main()
{
    char data[64];
    if (fgets(data, sizeof data, stdin)) {
        // input has worked, do something with data
    }
}

(未テスト)

18
glglgl

長さがわからないファイル(stdinを含む)から入力を読み取る場合、getlineが処理するため、scanfまたはfgetsよりもgetlineを使用した方がよい場合がよくあります。入力された文字列を受け取るためにヌルポインタを提供する限り、文字列のメモリ割り当てが自動的に行われます。この例で説明します:

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

int main (int argc, char *argv[]) {

    char *line = NULL;  /* forces getline to allocate with malloc */
    size_t len = 0;     /* ignored when line = NULL */
    ssize_t read;

    printf ("\nEnter string below [ctrl + d] to quit\n");

    while ((read = getline(&line, &len, stdin)) != -1) {

        if (read > 0)
            printf ("\n  read %zd chars from stdin, allocated %zd bytes for line : %s\n", read, len, line);

        printf ("Enter string below [ctrl + d] to quit\n");
    }

    free (line);  /* free memory allocated by getline */

    return 0;
}

関連する部分:

char *line = NULL;  /* forces getline to allocate with malloc */
size_t len = 0;     /* ignored when line = NULL */
/* snip */
read = getline (&line, &len, stdin);

lineNULLに設定すると、getlineはメモリを自動的に割り当てます。出力例:

$ ./getline_example

Enter string below [ctrl + d] to quit
A short string to test getline!

  read 32 chars from stdin, allocated 120 bytes for line : A short string to test getline!

Enter string below [ctrl + d] to quit
A little bit longer string to show that getline will allocated again without resetting line = NULL

  read 99 chars from stdin, allocated 120 bytes for line : A little bit longer string to show that getline will allocated again without resetting line = NULL

Enter string below [ctrl + d] to quit

したがって、getlineを使用すると、ユーザーの文字列の長さを推測する必要がありません。

15
David C. Rankin
#include<stdio.h>

int main()
{
    char str[100];
    scanf("%[^\n]s",str);
    printf("%s",str);
    return 0;
}

入力:文字列を読み取ります
ouput:文字列を出力します

このコードは、上記のように文字列にギャップを付けて出力します。

4
Ananth Reddy

使用する場所を指すポインタが必要です。

このコードを試してください:

char Word[64];
scanf("%s", Word);

これにより、長さ64の文字配列が作成され、入力が読み取られます。入力が64バイトより長い場合、Word配列がオーバーフローし、プログラムの信頼性が低下することに注意してください。

Jensが指摘したように、文字列の読み取りにscanfを使用しない方が良いでしょう。これは安全な解決策です。

char Word[64]
fgets(Word, 63, stdin);
Word[63] = 0;
1
Juho