質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.61%

  • C

    3570questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ループ内のsscanfの使い方がわかりません

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 184

wagon

score 3

 前提・実現したいこと

C言語でデータ文字列を変換し、構造体の配列に格納する関数を作ろうとしています。
プログラムを実行すると、ヘッダファイル内のsscanf関数の実行で動作が停止してしまいます。
正しく読み取りたいのですがどうすれば実現できるでしょうか?

 発生している問題・エラーメッセージ

ヘッダファイル内のvoid set_data_studentの関数内にあるsscanfを実行中に問題が起きていることだけわかりました。

エラーメッセージ
Microsoft Visual C++ 2010 Express
Run-Time Check Failure #3 - The variable 'e' is being used without being initialized.
中断 継続 無視

 該当のソースコード

ソースコード


//mystack ヘッダファイルの一部

ifndef MYSTACK_H

define MYSTACK_H

include <stdio.h>

include <stdlib.h>

include <string.h>

struct student
{
char name[12];
int math;
int eng;
};
//struct student構造体オブジェクトのメンバに値を格納する関数
struct student *set_student(char *n, int m, int e)
{
struct student *ps = NULL;
ps = (struct student*)malloc(1 * sizeof(struct student));
if(ps == NULL)
{
puts("記憶域の確保に失敗しました");
return NULL;    
}
strcpy(ps->name, n);
ps->math = m;
ps->eng = e;
return ps;
}
/*--データ文字列から数値や文字列にデータ変換をし構造体にまとめて管理する関数--*/
void set_data_student(char *data[100], struct student *seito[100],int length)
{
char *n;
int m,e,i;
for(i=0;i<length;i++)
{
sscanf(data[i],"%s%d%d",&n[0],m,e);//<-ここでエラーとなりました
seito[i] = set_student(&n[0],m,e);
}
}

endif

 試したこと

ソースファイル内でset_data_student関数の引数には問題はないようでした。

 補足情報(FW/ツールのバージョンなど)

Microsoft Visual C++ 2010 Express を使用しました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

こうですかね

void set_data_student(char *data[100], struct student *seito[100], int length)
{
    char n[12];
    int m, e;

    for (int i = 0; i < length; i++)
    {
        sscanf(data[i], "%s%d%d", n, &m, &e);
        seito[i] = set_student(n, m, e);
    }
}
  • The variable 'e' is being used without being initialized. と指摘されているとおり,変数 e の値は初期化されておらず,このまま実行しても値は不定です。「値を渡す」のではなく「変数に値をセットする」という使い方をしたいのであれば,修正例のように &e として変数へのポインタとして渡す必要があります。 m に関しても同様です。
  • &n[0] は n で十分です。
  • データ格納領域を実際に作らずに sscanf で文字列を格納することはできないので,char *n; ではなく char n[12]; として宣言してください。

【蛇足】

  • バッファオーバーランの危険性があります。文字列が12文字以上入力されてもプログラムが落ちないようにしたいのであれば, 標準入力から安全に文字列を受け取る方法いろいろ - Qiita を参考に改良してください。
  • 設計上の問題ですが,実際に実用的なプログラムをもし作るのであれば,「malloc した領域へのポインタに構造体を書き込んでそのポインタを返す関数」ではなく「引数で受け取ったポインタが指す領域に構造体を書き込む関数」というデザインにすべきです。構造体に含まれる文字列が固定長であれば,そもそもメモリを動的に確保せずとも使えます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/18 02:16 編集

    Microsoftの独自拡張ですが,scanf_s / sscanf_s などのよりメモリまわりを安全にした関数も存在します。

    scanf_s() で文字列を入力
    http://www.eonet.ne.jp/~maeda/cpp/scanf.htm

    標準を意識せずにとりあえず Windows 上でコンパイルできればいいのであれば,書式部分にごちゃごちゃかくよりも引数としてサイズを指定できるこちらを使ったほうがいいかもしれません。

    キャンセル

  • 2018/06/18 03:03

    丁寧な回答をありがとうございます。無事、問題は解決しました。
    プログラミング自体まだ始めたばかりで、補足説明もとてもいい勉強になりました!
    今回のプログラムも実用的なものに改良していけたらと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3570questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。