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

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

新規登録して質問してみよう
ただいま回答率
85.30%
C

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

3回答

656閲覧

Visual Studioでscanf_s後にprintfが表示されない問題の原因と対処法を教えてください

zikyu1113yen

総合スコア0

C

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

1クリップ

投稿2025/06/03 07:48

実現したいこと

・C言語で構造体の配列を使い、5人分の社員情報(名前・年齢・番号など)を入力し、最後にその情報をprintfで表示したい。

発生している問題・分からないこと

・scanf_sで情報を入力した後、printfで表示しようとしても、何も出力されない。

・プログラムはエラーも警告も出さず、正常終了しているように見える。

・printfの出力がまったくされず、デバッグの手がかりがない。

該当のソースコード

typedef struct employee_info { short num; char name[20]; char department[4]; short phone; short age; int salary; } employee_info; int main(void) { employee_info person[5]; employee_info* p = person; for (int i = 0; i < 5; i++) { printf("%d件目\n", i + 1); printf("従業員番号: "); scanf_s("%hd", &p[i].num); printf("名前: "); scanf_s("%s", p[i].name, sizeof(p[i].name)); printf("部門: "); scanf_s("%s", p[i].department, sizeof(p[i].department)); printf("年齢: "); scanf_s("%hd", &p[i].age); printf("内線番号: "); scanf_s("%hd", &p[i].phone); printf("給与: "); scanf_s("%d", &p[i].salary); } for (int i = 0; i < 5; i++) { printf("%d人目: %s\n", i + 1, p[i].name); printf("年齢: %hd\n", p[i].age); printf("従業員番号: %hd\n", p[i].num); printf("部門: %s\n", p[i].department); printf("内線番号: %hd\n", p[i].phone); printf("給与: %d\n", p[i].salary); } return 0; }

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

試したこと
scanf_sの第3引数にsizeof(p[i].name)のようにサイズを正しく指定。

数値の読み込みには&をつけてアドレス渡しをしている。

入力の直後にwhile (getchar() != '\n');を入れて、バッファの改行を処理。

fflush(stdout);をprintfの後に書いてみたが効果なし。

fgetsへの切り替えも試したが、入力のタイミングがずれたり改行が残ったりしてうまくいかず断念。

入力・出力の箇所を単純化してみたが、現象は変わらず。

補足

使用環境は Visual Studio。

構造体の定義やループ構造自体にはエラーは出ておらず、入力時に明らかな異常は見られない。

printfが実行されているかのデバッグが非常に難しい状態。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zikyu1113yen

2025/06/03 07:49

初めてまだ2か月でまだわからないことばかりですが、どなたかご指導よろしくお願いします。
zikyu1113yen

2025/06/03 07:50

ちなみにstructはテキストの指定された名前、指定された大きさで設定しています
TakaiY

2025/06/03 08:04

質問は投稿した後でも編集できますので、追加の情報などは質問を編集して追記したほうがいいですよ。
TakaiY

2025/06/03 08:06

> printfで表示しようとしても、何も出力されない。 何も出力されないとはどういう状況でしょうか? 出力されないというのは、最後の方の「for (int i = 0; i < 5; i++) {」のループの中のことだと思いますが、その中の年齢なども表示されないのでしょうか? > デバッグの手がかり とありますが、デバッガでステップ実行して途中の変数の内容を確認したりしていますか?
zikyu1113yen

2025/06/03 09:44

>何も出力されないとは、具体的にどのような状況でしょうか? そうなんです……本当に何も表示されないんです。 >デバッグの手がかりについて 申し訳ありません、私の説明不足でした。 デバッグして確認したところ、下の for 文で処理している値が、何も入力されていないときに表示される数値とまったく同じでした。 追加情報で申し訳ないのですが、上の「名前」や「部門」の入力欄を削除して実行してみたところ、下の for 文はかなりうまく動作するようなんです……
jimbe

2025/06/03 10:51

scanf_s の戻り値をチェックしてみては如何でしょうか。
fana

2025/06/04 02:00 編集

(言うまでもないような話ですが)私ならとりあえず各 scanf_s の直後に入力されたハズの物をそのまま出力する printf を入れてみたらどうなるのか? とかを真っ先に試してみるかな,とか思いました. あとは,何が起こってるのかわからない場合には,私ならとりあえず物事を単純化してみるかな,とか. 「要素を減らす」というか.例えば, * person[5] じゃなくて person としたプログラム(配列無し:データ1つだけ)でも同様のことが起こるのか? * struct無しで,単純に num とか name とかいう変数がバラで存在している世界でも同様のことが起こるのか? * numだけとかnameだけみたいに,データの種類を減らしてみたらどうなるのか? * sizeofみたいなのはとりあえず「この値になるハズだよね」っていう値をダイレクトに書いてみる * etc とにかく色々と簡素化していくとどこかの時点で問題が起きなくなるのであれば,そこで何かヒントが得られるんじゃなかろうか? っていう話.
little_street

2025/06/04 14:07

改善策になるかはわかりませんが,もし「部門」への入力が半角4文字以上または全角(漢字,かな等)2文字以上なら,そのための領域(char department[4];)を増やす必要がありそうです。全角を入力する場合はエンコーディング方式も関係するので一概には言えませんが,全角1文字4バイト+半角1文字1バイト+終端用1バイトで設定してみてください。
hiroki-o

2025/06/04 15:12

Windows 11、Visual Studio 2022で確認しましたが、再現しませんでした。 下記の情報を「質問を編集して」追記してください。 - Windows 11か10か - Visual Studioのバージョン(2022,2019...) - ソースファイルの拡張子は、*.cか*.cppか(ソースはC言語ですが、C++でビルドしていないか) - includeが省略されているが、#include <stdio.h>でよいか - ビルドは64bitか32bitか - 入力したテストデータの例
YT0014

2025/06/05 02:43 編集

Windows 11 Pro(64bit、24H2、26100.4061)。VisualStudio2022(17.10.5)で現象を確認 =>ごめんなさい、誤認かも。正常動作を確認しました なお、入力値は、全て半角英数1文字 名前と部門用のscanf_s()で、警告あり
cametan

2025/06/05 03:50

ごめん。バカバカしいたぁ思うけど一応確認を取る。 提示コードは完全コピペ?まさか、とは思うけど#include <stdio.h>を書き忘れた・・・ってこたぁ無いよね?
YT0014

2025/06/05 04:46

>zikyu1113yen 質問編集にて、テスト時の入力値と、可能であれば実際の画面のスクリーンショット画像も、ご提示ください また、私がやった誤認ですが、画面スクロールに気づかず、出力表示を、入力時表示と間違えている可能性はないですか?
cametan

2025/06/05 18:30

あと、もう一つ。 バカバカしいたぁ思うけど、「出力されたのに出力されてない」って思い込むケース。 これもあるんだ。 特にこのプログラムのように、入力のプロンプトと出力に大して差がない場合、一瞬で出力が終わっちゃって「出力された」と気付かない。 んで意外とパソコンの、特に端末(DOS窓)のスクロールがカクカクしててスムーズじゃねぇんだよな。だから「出力が増えてても気付かない」って事があり得るんだ。 出力のループの直前に、例えばputs("----------------");とか入れておいて、「これ以降は出力」ってサインを入れておけばどうなのか気づきやすくなる。
guest

回答3

0

これ、難しいのがなぁ。

まず、C11以降で確かにscanf_sってのが定義されている。
一方、それってオプショナルで、事実上、Microsoftの処理系でしか実装されていない(※)。
と言う事はポータブルじゃない、って事になるんだ。

もう一つの問題が「どうやって字数を数えてるのか」。
これって、かなりややこしいんだよ。
基本的に貴方の書いてるコードって「入力がASCIIコード前提」って話になるんだ。っつーかならざるを得ない。
つまり、仮に日本語入力、って前提になると、もう型からして違う、って話になるわけ。
いや、実質上、この辺はコンパイラによって、独自に解決してくれるケースも多いんだけど、その辺実装依存になる、っつーか・・・・・・。
つまり、Microsoftの処理系が「どう解釈するのか」ってのを熟知せなアカン、って話になるんじゃないかなぁ・・・。
多分。
C11以降でUTF-8を扱えるようになってる筈、なんだけど、この辺、甚だ不安定なんだよな。仕様上(苦笑)。
よって、前提としては、(日本と違って世界的には)デファクトスタンダードなC99、あるいはJIS C規格を考慮すると、そもそもwchar_tを使わな「数えられない」と思う。
そしてその辺がかなりややこしいんだ。

生憎、僕はそんなにCが得意じゃない(どころか嫌いだ・笑)んだけど、調べてみて、ポータブルに書く、って前提だと次のようになるんじゃなかろうか。
詳しい話は識者の人(Cが得意な人)が解説してくれれば嬉しいんだけど(人任せ・笑)・・・。

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <inttypes.h> 4#include <wchar.h> 5#include <locale.h> 6 7#define N 5 8 9static wchar_t buffer[41]; 10 11typedef struct employee_info 12{ 13 int16_t num; 14 wchar_t name[21]; 15 wchar_t department[5]; 16 int16_t phone; 17 int16_t age; 18 int32_t salary; 19} 20 employee_t; 21 22int main(void) 23{ 24 employee_t p[N] = {0}; 25 26 setlocale(LC_ALL, ""); 27 28 for (size_t i = 0; i < N; i++) 29 { 30 wprintf(L"%" PRIu64 L"件目\n", (uint64_t)(i + 1)); 31 32 wprintf(L"従業員番号: "); 33 fgetws(buffer, 5, stdin); 34 buffer[wcscspn(buffer, L"\n")] = L'\0'; 35 p[i].num = (int16_t)wcstol(buffer, NULL, 10); 36 37 wprintf(L"名前: "); 38 fgetws(buffer, 21, stdin); 39 buffer[wcscspn(buffer, L"\n")] = L'\0'; 40 wcscpy(p[i].name, buffer); 41 42 wprintf(L"部門: "); 43 fgetws(buffer, 5, stdin); 44 buffer[wcscspn(buffer, L"\n")] = L'\0'; 45 wcscpy(p[i].department, buffer); 46 47 wprintf(L"年齢: "); 48 fgetws(buffer, 3, stdin); 49 buffer[wcscspn(buffer, L"\n")] = L'\0'; 50 p[i].age = (int16_t)wcstol(buffer, NULL, 10); 51 52 wprintf(L"内線番号: "); 53 fgetws(buffer, 5, stdin); 54 buffer[wcscspn(buffer, L"\n")] = L'\0'; 55 p[i].phone = (int16_t)wcstol(buffer, NULL, 10); 56 57 wprintf(L"給与: "); 58 fgetws(buffer, 10, stdin); 59 buffer[wcscspn(buffer, L"\n")] = L'\0'; 60 p[i].salary = (int32_t)wcstol(buffer, NULL, 10); 61 } 62 63 for (size_t i = 0; i < N; i++) 64 { 65 wprintf(L"%" PRIo64 L"人目: %ls\n", (uint64_t)(i + 1), p[i].name); 66 wprintf(L"年齢: %" PRId16 L"\n", p[i].age); 67 wprintf(L"従業員番号: %" PRId16 L"\n", p[i].num); 68 wprintf(L"部門: %ls\n", p[i].department); 69 wprintf(L"内線番号: %" PRId16 L"\n", p[i].phone); 70 wprintf(L"給与: %" PRId32 L"\n", p[i].salary); 71 } 72 73 return EXIT_SUCCESS; 74 75} 76

wchar.hってヘッダで定義された関数を多用するのが一番信頼性が高いんじゃないか。
んで、読み込みはscanfとかwscanfを使うよかfgetwsを使う。バッファbufferを定義してそこに文字列として読み込むんだけど、取り込んだ改行文字(L"\n")を、ワイド文字の終端文字、L'\0'へと変換する。=> L"\n"の位置検索にwcscspnを使用
その後、それを数値データに変換する(wcstol)なり、ワイド文字列とするなり、で構造体のスロットに代入するとかコピー(wcscpy)する。
かなり面倒くさいんだけど、多分これならどのコンパイラでも動いてくれるんじゃないかな。恐らく。多分。

※: 外野から見ると、Microsoftが提案した機能をCの仕様策定委員会が「敢えて」オプションにしたり、または他のグループが提案したブツもまたオプション化して、Microsoftがそれを実装しなかったり、と、策定委員会がMicrosoft vs. 「その他」に分裂してるように見える。
全く、「なにやっとんねん」と言うカンジだ(笑)。何のための標準化委員会なんだかサッパリ分からん(笑)。
いずれにせよ、「その他」にとってはMicrosoftは「怖い」会社なんだろう。

なお、日本国内では公式ではC言語 = C99なんだけど、長い間Microsoftはキャッチアップして来なかった。現在では最新のC言語仕様はC23と呼ばれるモノだが、Microsoftでは、知ってる限り、現在ではC17に対応はしている。

参考: Visual Studio に C11 および C17 サポートをインストールする

また、C/C++のライブラリ関数に付いては、IBMのページが良くまとまっている。

投稿2025/06/08 16:41

編集2025/06/09 05:05
cametan

総合スコア57

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Windows 11、Visual Studio 2022で確認しました。
コメントに書いた通り、こちらの環境では現象は再現しませんでした。

以下、今回の現象と直接関係無いと思いますが、修正したほうがよい箇所を指摘します。

標準入出力ライブラリーの明記

#include <stdio.h>

変数のゼロ初期化

//employee_info person[5]; employee_info person[5] = {0};

文字列を格納する領域と、NULL終端の意識

//scanf_s("%s", p[i].name, sizeof(p[i].name)); scanf_s("%19s", p[i].name, (unsigned)sizeof(p[i].name)); rewind(stdin); //scanf_s("%s", p[i].department, sizeof(p[i].department)); scanf_s("%3s", p[i].department, (unsigned)sizeof(p[i].department)); rewind(stdin);

投稿2025/06/07 10:14

hiroki-o

総合スコア1414

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Visual Studioでscanf_s後にprintfが表示されない問題の原因と対処法を教えてください

原因はあなたの書いたコードの不具合があるため、ですね
もっと勉強して、そういう不具合がない正しいコードが書けるようになりましょう。

投稿2025/06/05 22:38

y_waiwai

総合スコア88171

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問