ページ 1 / 1
構文エラーに悩まされています
Posted: 2011年8月07日(日) 14:08
by kerotan0820
今現在、構造体、関数、ポインタ…etc を身につけるために、名前と生年月日を管理するアプリケーションを作ることにしました。
今現在、プログラムは以下のような状態です。
コード:
#include <stdio.h>
/***************************************************************
**********************名前、生年月日の構造体********************
***************************************************************/
struct data1 {
char name[64]; /* 名前 */
int year; /* 年 */
int manth; /* 月 */
int day; /* 日 */
};
int main(void)
{
int menu=0;
int quantity=0; /* データ数 */
struct data1 birth[200]; //200人分の保存領域を確保
birth[0].name = "Kerotan0820" ; //表示テストのために代入
birth[0].year = 1994; // 〃
/***************今週、今月の誕生日者指名一覧表示***************/
//表示関数
/***************************************************************
**********書き込み、読み込み、その他メニュー(分岐)************
***************************************************************/
printf("新規データの入力 :1\n"
"データの編集 :2\n"
"アルファベット順名前一覧:3\n\n");
printf("入力:");
scanf( "%d", &menu );
switch (menu){
case 0: //表示関数 テスト
void OUTPUT_DATA(birth);
break;
case 1:
/******新規データの入力******/
printf("新規データの入力\n");
break;
case 2:
/******データの編集******/
printf("データの編集\n");
break;
case 3:
/******アルファベット順名前一覧******/
printf("アルファベット順名前一覧\n");
break;
default:
/******入力エラーメッセージ******/
printf("入力エラーメッセージ\n");
break;
}
void OUTPUT_DATA(struct birth[])
{
printf("%s %4d\n", birth[0].name , birth[0].year );
return 0;
}
return 0;
}
久しぶりのプログラミングでもあるので、switch文などの単純な文法でもミスをしかねない…ということから、プログラムを少しいじるたびにデバッグを行っていたのですが、関数を追加したところで、突如エラーが多出し、取り返しがつかなくなりました。
こちらのサイトの、例題3、例題4を参考に、値渡しを再現しようとしていたところです。
しかし、デバッグしてみると以下の通りのエラーが出ました。・
error C2106: '=' : 左のオペランドが、左辺値になっていません。
error C2143: 構文エラー : ';' が '型' の前にありません。
error C2143: 構文エラー : ';' が '型' の前にありません。
error C2059: 構文エラー : 'return'
error C2059: 構文エラー : '}'
エラーの原因を調べてみたものの、 main関数までに 中括弧をつけ忘れてはいないか、などといった書き込みが有りましたが、見当たりませんでした…。
構造体を実用するのは初めてなので、構文上気づいてないミスがあるかも分かりません。
ご指摘いただけると幸いです。
よろしくお願いします。
Visual C++ 2008 Express Edition
Win7
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 14:10
by xxx
関数内で関数を宣言することはできないのでOUTPUT_DATA()をmainの前に書けばいいと思います。
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 14:23
by kerotan0820
roxion様>>
回答ありがとうございます。
main関数の前に、移動させてみましたが、以下のようにエラーが出ました
error C2055: 型リストではなく、仮パラメータ リストが必要です。
error C2065: 'birth' : 定義されていない識別子です。
error C2109: 配列または、ポインタでない変数に添字が使われました。
error C2065: 'birth' : 定義されていない識別子です。
error C2109: 配列または、ポインタでない変数に添字が使われました。
error C2106: '=' : 左のオペランドが、左辺値になっていません。
error C2143: 構文エラー : ';' が '型' の前にありません。
思い当たる点を数点改善しました。
コード:
#include <stdio.h>
/***************************************************************
**********************名前、生年月日の構造体********************
***************************************************************/
struct data1 {
char name[64]; /* 名前 */
int year; /* 年 */
int manth; /* 月 */
int day; /* 日 */
}birth;
void OUTPUT_DATA(struct data1 birth[])
{
printf("%s %4d\n", birth[0].name , birth[0].year );
return 0;
}
int main(void)
{
int menu=0;
int quantity=0; /* データ数 */
struct data1 birth[200]; //200人分の保存領域を確保
birth[0].name = "Kerotan0820" ; //表示テストのために代入
birth[0].year = 1994; // 〃
/***************今週、今月の誕生日者指名一覧表示***************/
//表示関数
/***************************************************************
**********書き込み、読み込み、その他メニュー(分岐)************
***************************************************************/
printf("新規データの入力 :1\n"
"データの編集 :2\n"
"アルファベット順名前一覧:3\n\n");
printf("入力:");
scanf( "%d", &menu );
switch (menu){
case 0: //表示関数 テスト
void OUTPUT_DATA( birth );
break;
case 1:
/******新規データの入力******/
printf("新規データの入力\n");
break;
case 2:
/******データの編集******/
printf("データの編集\n");
break;
case 3:
/******アルファベット順名前一覧******/
printf("アルファベット順名前一覧\n");
break;
default:
/******入力エラーメッセージ******/
printf("入力エラーメッセージ\n");
break;
}
return 0;
}
エラーは
error C2106: '=' : 左のオペランドが、左辺値になっていません。
error C2143: 構文エラー : ';' が '型' の前にありません。
この2つだけになりましたが、どうもこの2つがよくわかりません。
a=1; は ok
1=a; みたいなことをすると出るエラーと解説に書いてあったのですが、
構造体への値の代入において、間違っている点が思い当たりません。
ご教示いただけると幸いです。
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 14:41
by YuO
エラーの起きた行番号も書いてもらえると,読む側にとってわかりやすいです。
kerotan0820 さんが書きました:error C2106: '=' : 左のオペランドが、左辺値になっていません。
これは,33行目
kerotan0820 さんが書きました:コード:
birth[0].name = "Kerotan0820" ; //表示テストのために代入
で起きているのでしょうか。
data1::nameはcharの配列ですから,「変更不可能な左辺値」です。
# なので,エラーメッセージがちょっとおかしい。わからんでもないですが。
charの配列に文字列を代入することができないので (初期化時除く),charの配列に文字列を設定するにはstrcpy関数を使います。
で,58行目
kerotan0820 さんが書きました:コード:
void OUTPUT_DATA( birth );
は
コード:
OUTPUT_DATA( birth );
の間違いでしょうか。
# あまり関数内で関数の宣言はしないでしょうから除外。
なお,C/C++では慣習的に大文字と_からなる識別子は#defineされたものに使います。
関数名には使わない方がよいでしょう。
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 14:42
by 初級者
kerotan0820 さんが書きました:
error C2106: '=' : 左のオペランドが、左辺値になっていません。
error C2143: 構文エラー : ';' が '型' の前にありません。
これらのエラーが、ソースコードの何行目で出ていますか?
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 14:45
by bitter_fox
kerotan0820 さんが書きました:
コード:
#include <stdio.h>
/***************************************************************
**********************名前、生年月日の構造体********************
***************************************************************/
struct data1 {
char name[64]; /* 名前 */
int year; /* 年 */
int manth; /* 月 */
int day; /* 日 */
}birth;
void OUTPUT_DATA(struct data1 birth[])
{
printf("%s %4d\n", birth[0].name , birth[0].year );
return 0;
}
int main(void)
{
birth[0].name = "Kerotan0820" ; //表示テストのために代入
void OUTPUT_DATA( birth );
}
error C2106: '=' : 左のオペランドが、左辺値になっていません。
error C2143: 構文エラー : ';' が '型' の前にありません。
error C2106は、
birth[0].name = "Kerotan0820"が原因で、配列に対して文字列リテラルのアドレスを代入しようとしてます。
strcpyなどを使用するかnameをポインタにしてください。
error C2143は、
void OUTPUT_DATA(birth)が原因で、この位置にvoidが来るのは間違っています。
単にOUTPUT_DATA(birth);としてください。
あと、インデントがバラバラなので整えて、OUTPUT_DATAという名前もマクロっぽいので関数の名前らしいもの変えておいた方が良いですよ。
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 16:54
by kerotan0820
bitter_fox様、初心者様、YuO 様、
回答ありがとうございます。
皆様の回答を参考に以下のように修正致しました。
コード:
#include <stdio.h>
#include <string.h>
/***************************************************************
**********************名前、生年月日の構造体********************
***************************************************************/
struct data1 {
char name[64]; /* 名前 */
int year; /* 年 */
int manth; /* 月 */
int day; /* 日 */
}birth;
void outputdata(struct data1 birth[])
{
printf("%s %4d\n", birth[0].name , birth[0].year );
return 0;
}
int main(void)
{
int menu=0;
int quantity=0; /* データ数 */
struct data1 birth[200]; //200人分の保存領域を確保
char name1[30]={"Kota ama"};
strcpy(birth[0].name , name1); //表示テストのために代入
birth[0].year = 1994; // 〃
/***************今週、今月の誕生日者指名一覧表示***************/
//表示関数
/***************************************************************
**********書き込み、読み込み、その他メニュー(分岐)************
***************************************************************/
printf("新規データの入力 :1\n"
"データの編集 :2\n"
"アルファベット順名前一覧:3\n\n");
printf("入力:");
scanf( "%d", &menu );
switch (menu){
case 0: //表示関数 テスト
outputdata( birth );
break;
case 1:
/******新規データの入力******/
printf("新規データの入力\n");
break;
case 2:
/******データの編集******/
printf("データの編集\n");
break;
case 3:
/******アルファベット順名前一覧******/
printf("アルファベット順名前一覧\n");
break;
default:
/******入力エラーメッセージ******/
printf("入力エラーメッセージ\n");
break;
}
return 0;
}
お陰様でエラーは改善されました。
本当にありがとうございます。
ちなみに、名前の入力は、gets(); などで配列に代入、
strcpy( );で birth[0].year にコピー、それを表示すれば、良いでしょうか?
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 17:11
by non
気になる点ですが、
コード:
struct data1 {
char name[64]; /* 名前 */
int year; /* 年 */
int manth; /* 月 */
int day; /* 日 */
}birth;
で、birthを宣言しておいて、再び、ローカルで
コード:
struct data1 birth[200]; //200人分の保存領域を確保
してますから、グローバルのbirthはいらないですね。
コード:
char name1[30]={"Kota ama"};
初期値を代入していますし、、構造体のメンバーでは64にしていますから、30を使っている意味がわかりません。
30という数値は書かないのが一般的でしょう。
コード:
void outputdata(struct data1 birth[])
{
printf("%s %4d\n", birth[0].name , birth[0].year );
return 0;
}
戻り値がvoidですから、return 0 はまずいです。
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 17:28
by kerotan0820
>>non様
ご指摘ありがとうございます。
確かに、30と指定する必要は有りませんでした。
訂正しました。
void型なのに対し、return 0を返している、これはwarningも出ていたので、迷っていたところでした。
指摘ありがとうございます。
reuturn文を記述しないと、voidで宣言された関数が、値を返したなどと warningが出ますが、気に止めることでは無いでしょうか。
それと、今現在、修正を食わせてこのようになっておりますが、
コード:
#include <stdio.h>
#include <string.h>
/***************************************************************
**********************名前、生年月日の構造体********************
***************************************************************/
struct data1 {
char name[64]; /* 名前 */
int year; /* 年 */
int manth; /* 月 */
int day; /* 日 */
};
void outputdata(struct data1 birth[])
{
printf("%s %4d\n", birth[0].name , birth[0].year );
}
void main(void)
{
int menu=0;
int quantity=0; /* データ数 */
struct data1 birth[200]; //200人分の保存領域を確保
char name1[]="Kota ama";
/* strcpy(birth[0].name , name1); //表示テストのために代入 */
birth[0].year = 1994; // 〃
/***************今週、今月の誕生日者指名一覧表示***************/
//表示関数
/***************************************************************
**********書き込み、読み込み、その他メニュー(分岐)************
***************************************************************/
printf("新規データの入力 :1\n"
"データの編集 :2\n"
"アルファベット順名前一覧:3\n\n");
printf("入力:");
scanf_s( "%d", &menu );
switch (menu){
case 0: //表示関数 テスト
scanf_s("%s",&name1);
strcpy(birth[0].year , name1);
outputdata( birth );
break;
case 1:
/******新規データの入力******/
printf("新規データの入力\n");
break;
case 2:
/******データの編集******/
printf("データの編集\n");
break;
case 3:
/******アルファベット順名前一覧******/
printf("アルファベット順名前一覧\n");
break;
default:
/******入力エラーメッセージ******/
printf("入力エラーメッセージ\n");
break;
}
return 0;
}
名前を入力すると、エラーが出てしまいます。
(59) : warning C4047: '関数' : 間接参照のレベルが 'char *' と 'int' で異なっています。
(59) : warning C4024: 'strcpy' : の型が 1 の仮引数および実引数と異なります。
(59) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
(74) : 'strcpy' の宣言を確認してください。
このような 警告が出ており、関係があるだろうと、思ってはいるものの、どう訂正すれば良いのか、分かりません。
どうか回答の方よろしくお願いします。
度々すみません。
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 18:02
by 初級者
名前を年にstrcpyするのは、どうみてもおかしいです。
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 18:18
by non
58 行目の scanf_s("%s",&name1);
には、2つの問題があります。
まず、大きな問題は
char name1[]="Kota ama";
ですから、name1だけ書くと、これは配列の先頭アドレスを示します。すでにアドレスを示しているのに、&を
つけることがおかしいです。 &をどうしてもつけたいなら &name1[0] と書きますが、これは name1と書くのと同義です。
小さい問題としては、name1[]の配列は9文字分しか確保されていません。これにscanfで文字列を格納するとき、8文字以上の
入力をすると暴走の可能性があります。別の、入力用の配列を64文字分確保しておくべきでしょう。
もちろん、初級者さんが仰っていることもね。
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 21:15
by kerotan0820
初級者様>>
ご指摘ありがとうございます。
完全に見落としていました;
non様>>
試行錯誤の上、エラーはすべて改善できたのですが、文字列が表示されません…。
コード:
#include <stdio.h>
#include <string.h>
/***************************************************************
**********************名前、生年月日の構造体********************
***************************************************************/
struct data1 {
char name[64]; /* 名前 */
int year; /* 年 */
int manth; /* 月 */
int day; /* 日 */
};
void outputdata(struct data1 birth[])
{
printf("%s %4d\n", birth[0].name , birth[0].year );
}
main(void)
{
int menu=0;
int quantity=0; /* データ数 */
struct data1 birth[200]; //200人分の構造体を確保
char name1[50];
/* strcpy(birth[0].name , name1); //表示テストのために代入 */
birth[0].year = 1994; // 〃
/***************今週、今月の誕生日者指名一覧表示***************/
//表示関数
/***************************************************************
**********書き込み、読み込み、その他メニュー(分岐)************
***************************************************************/
printf("新規データの入力 :1\n"
"データの編集 :2\n"
"アルファベット順名前一覧:3\n\n");
printf("入力:");
scanf_s( "%d", &menu ); //どういった動作を行うのか入力
switch (menu){
case 0: //表示関数 テスト
scanf_s("%s",name1);
printf("%s\n",name1); //テスト表示
strcpy(birth[0].name , name1);
printf("%s\n",birth[0].name); //テスト表示
outputdata( birth );
break;
case 1:
/******新規データの入力******/
printf("新規データの入力\n");
break;
case 2:
/******データの編集******/
printf("データの編集\n");
break;
case 3:
/******アルファベット順名前一覧******/
printf("アルファベット順名前一覧\n");
break;
default:
/******入力エラーメッセージ******/
printf("入力エラーメッセージ\n");
break;
}
return 0;
}
scanfが文字列なのに %d になってたり、そういったミスを幾つか見つけて訂正してみたのですが、もんだいが何か分からず困っています。
(74) : 'strcpy' の宣言を確認してください。
などと警告が出ているのですが、関係ありますでしょうか
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 21:57
by 初級者
メニューの選択肢にない
case 0
というのは何でしょうか?
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 22:51
by non
まず、
>main(void)
int main(void)
にしましょう。C言語ではエラーになりませんが、決まりですから。
>(74) : 'strcpy' の宣言を確認してください。
>などと警告が出ているのですが、関係ありますでしょうか
C4996の警告なら、今のところ無視しましょう。
>scanf_s("%s",name1);
scanfとscanf_sでは、使い方が少し異なります。調べましょう。
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 23:38
by kerotan0820
>>初級者様
入力、出力の両方を関数で扱いたいと思っておりまして、両方の関数化を同時に行おうとしたら私のことですから、エラーが出た際、原因究明が難しくなると思い、あくまで出力の関数化の実装のためのテスト(実験)として case 0 を用意しました。
non様からご指摘いただいたscanf と scanf_sの使い方の違いを理解したら、case 0 を参考に 入出力の関数などを完成させたいと思っております。
Re: 構文エラーに悩まされています
Posted: 2011年8月07日(日) 23:46
by 初級者
では伺いますが、「文字列を表示しない」という現象は
下記のメニューで何を選択したときに起きているのでしょうか。
kerotan0820 さんが書きました:
コード:
printf("新規データの入力 :1\n"
"データの編集 :2\n"
"アルファベット順名前一覧:3\n\n");
Re: 構文エラーに悩まされています
Posted: 2011年8月08日(月) 00:00
by 初級者
メニュー番号の入力の後、何という文字列を入力したのかも教えてください。
Re: 構文エラーに悩まされています
Posted: 2011年8月08日(月) 00:01
by kerotan0820
>>初級者様
printfのことですか?
全ての処理で使うと思います。
多用しない関数は作るべきではありませんでしょうか;;
--追記--
>>メニュー番号の入力の後、何という文字列を入力したのかも教えてください。
non様に指摘していただいた _s をなくしたら無事問題なく動作したのですが、
それとは全く関係なしでお答えすれば良いのでしょうか。
文字列は Kota と入力しました。
kerotan0820 も試しましたし、ひらがなも漢字も試しました。
Re: 構文エラーに悩まされています
Posted: 2011年8月08日(月) 00:10
by 初級者
メニュー番号の、1~3、あるいは0のうち、
何を選択しましたか?と聞いたのでした。
printfのことは、何も聞いていません。
まあ、たぶん0を選択したのでしょうね。
Re: 構文エラーに悩まされています
Posted: 2011年8月08日(月) 00:19
by 初級者
scan_f の第3引数を適切に指定すればOKだと思いますので、
試してみてはいかがでしょうか。
Re: 構文エラーに悩まされています
Posted: 2011年8月08日(月) 00:41
by kerotan0820
初級者様>>
はい、0を選択しました。
メニューには有りませんが^^;
第三引数とは何でしょうか?
scanf("%64s"... とかそういう意味ですか?
Re: 構文エラーに悩まされています
Posted: 2011年8月08日(月) 08:08
by non
初級者 さんが書きました:scan_f の第3引数を適切に指定すればOKだと思いますので、
試してみてはいかがでしょうか。
scanf_sですね。
Re: 構文エラーに悩まされています
Posted: 2011年8月08日(月) 21:10
by kerotan0820
>>non様
なるほど、ありがとうございます。
それと、ついでに質問させていただきたいのですが、
このプログラムでは実用性を考えて作っているので、実際に構造体内の個人情報などを補助記憶装置に記憶したいと思っています。
データを記憶するのはどのような手法を取るのがベターなのでしょうか。
ゲームプログラミングの館にある、セーブデータを作る方法などを参考にやるのが望ましいですか?
Re: 構文エラーに悩まされています
Posted: 2011年8月08日(月) 23:29
by kerotan0820
追記で質問をさせていたいていましたが、件名と話が全く別になってしまいますので、やはり新規トピックとして質問させて頂きます。
ありがとうございました。