akkiy58
@akkiy58

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

[C言語]スペースを含む数字列を配列に格納したい (paiza)

C言語の標準入力で、スペースを含む数字列を配列に格納したい

使用環境:paiza io

現在paizaでC言語の勉強をしていて、ある問題を解くために、スペースを含む数字列が標準入力として与えられたら、スペースを除いて数字を1個ずつ配列に格納したいと思いました。

入力例)

5           (配列のサイズ)
1 2 3 4 5   (配列に格納したい数字列)

これを下記のように処理を行ってみました。

int main(void)    
    char str[1000];
    fgets(str, sizeof(str), stdin);
    
    int n;
    sscanf(str, "%d", &n);
    
    int data_1[n];
    fgets(str, sizeof(str), stdin);
    char *tp1;
    tp1 = strtok(str, " ");
    
    for (int i = 0; tp1; tp1 = strtok(NULL, " ")) {
        int x = 0;
        data_1[i] = atoi(tp1);
        printf("%d\n", data_1[i]);
    }

出力結果

1
2
3
4
5

こうしてみると配列にちゃんと格納されていると思ったのですが、次のように書き直してみると、

int main(void){
    char str[1000];
    fgets(str, sizeof(str), stdin);
    
    int n;
    sscanf(str, "%d", &n);
    
    int data_1[n];
    fgets(str, sizeof(str), stdin);
    char *tp1;
    tp1 = strtok(str, " ");
    
    for (int i = 0; tp1; tp1 = strtok(NULL, " ")) {
        int x = 0;
        data_1[i] = atoi(tp1);
    }
    
    for (int i = 0; i < n; i++) {
        printf("%d\n", data_1[i]);
    }
    
}

出力結果

5
32764
4198528
0
1611535728

というように結果が変わっていました。
どうしてこういうふうに動作が変わってしまうのか、分からなかったのでお知恵をお借りいただけないでしょうか?
よろしくお願いいたします。

0

2Answer

ポインタに気が取られてインデックスの更新ができてないように見えます。

    for (int i = 0; tp1; tp1 = strtok(NULL, " ")) {
        int x = 0;
        data_1[i] = atoi(tp1);
    }

この中で変数iが、ずっと0なのでdata_1[0]ばっかり更新してるからです。

-    for (int i = 0; tp1; tp1 = strtok(NULL, " ")) {
+    for (int i = 0; tp1; tp1 = strtok(NULL, " "),i++) {

変数iを増やせば正しくでると思いますよ。

1Like

Comments

  1. @akkiy58

    Questioner

    ホントですね…
    単純なところ失念しておりました💦

    ご指摘いただいたところを修正したら、しっかり動作することができました!
    ありがとうございます!

もう一つの方法として、sscanf(str, "%d", &x)がスペースや改行で区切られることを利用すると、次のようにも書けます。

#include <stdio.h>
int main(void){
    char str[1000];
    fgets(str, sizeof(str), stdin);

    int n;
    sscanf(str, "%d", &n);

    int data_1[n];
    fgets(str, sizeof(str), stdin);
    char *p = str;
    for (int i = 0; i < n; i++) {
        int l = sscanf(p, "%d", &data_1[i]);
        p += l + 1;
    }

    for (int i = 0; i < n; i++) {
        printf("%d\n", data_1[i]);
    }
}

paisa.ioで実行

1Like

Comments

  1. さらに、stdinから直接入力してしまえば、もっとシンプルに書けます。

    #include <stdio.h>
    int main(void){
        int n;
        scanf("%d", &n);
    
        int data_1[n];
        for (int i = 0; i < n; i++) {
            scanf("%d", &data_1[i]);
        }
    
        for (int i = 0; i < n; i++) {
            printf("%d\n", data_1[i]);
        }
    }
    

    paisa.ioで実行

  2. @akkiy58

    Questioner

    scanfを使うとこうもシンプルになるんですね!
    もう一度scanfについて勉強しなおしてみます。

    アドバイスありがとうございました!

  3. 解決でよろしければ、当Q&Aをクローズしていただければと思います。

Your answer might help someone💌