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

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

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

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

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Q&A

解決済

6回答

3478閲覧

Cのファイル読み書きに関する質問です

yusukee345

総合スコア31

C

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

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

0グッド

0クリップ

投稿2016/11/09 03:06

以下の問題が上手く行きません。
「キーボードから、文字列を入力し、それをファイルdata.txtに出力するプログラムを作りなさい。ただし、文字列として、qが入力された場合、キーボードからの入力、及び、データの書き込みは終了するものとする。

実行結果の例
文字列を入力してください:abc ← キーボードから入力
文字列を入力してください:cccccc ← キーボードから入力
文字列を入力してください:clanguage ← キーボードから入力
文字列を入力してください:q ← キーボードから入力

data.txtの内容
apple
car
airplane」(問題文ここまで)

Visual Studio2013で以下のプログラムを実行してみたのですが、”q”を入力してもdowhileループから抜け出せず、入力とデータ書き込みを終了できません。dowhileの条件設定かdowhileの範囲に問題があるだろうと踏んでいるのですが、私一人では実際どのように問題がおこっているのかが分かりません。どうすれば、”q”を入力してループを抜けることが出来るのかを教えて頂きたいです。

#include<stdio.h>
#include<stdlib.h>
#pragma warning(disable:4996)

#define size 256

void main(){
FILE* file;
char line[256];
line[0] = '\0';
file = fopen("c:\test\data.txt","w");
if (file == NULL){
printf("ファイルが開けません\n");
exit(1);
}
do{
printf("文字列を入力してください:");
scanf("%s", line);
fprintf(file, "%s", line);
}while(line != "q");
fclose(file);
file = fopen("c:\test\data.txt","r");
if (file == NULL){
printf("ファイルが開けません\n");
exit(1);
}
while (fgets(line, size, file) != NULL){
printf("%s ",line);
}
getchar();
}

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

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

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

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

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

guest

回答6

0

原因を簡単に説明すると、

  1. do-whileに指定している条件式に誤りがある
  2. 文字列と文字列の比較は、標準関数strcmp等を用いて行う必要がある
  3. C言語の仕様として、文字列と文字列を、直接、==演算子等で比較することができない
  4. C言語では、文字列はchar型の配列として表現されており、配列と配列は、直接、==演算子等で比較することができない
  5. 直接比較できない理由は、配列の名前(lineなど)を書くと、その先頭の要素の位置(アドレス)を表すことになっていて、アドレスとアドレスを比較するという意味になってしまうから
  6. ""で囲まれた文字列(リテラル)も、そのような文字列を格納している配列の先頭の要素の位置(アドレス)を表している
  7. つまり質問文で提示された条件式の場合、異なる配列のアドレスを比較することになってしまい、条件式が常に成り立つ(修正しました)
  8. なぜ配列の名前を書くと、アドレスを意味する仕様になっているかを書くと、C言語の開発者が、「そのほうがポインタを扱う際に便利だから」と考えたから
  9. C++言語の標準ライブラリでは、演算子を利用して比較することができるよう改善された

こんな感じです。2まで読めば分かると思います。

投稿2016/11/09 03:52

編集2016/11/09 08:09
majiponi

総合スコア1720

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

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

yusukee345

2016/11/09 06:09

わかりやすくまとまったポイントありがとうございます。
guest

0

ざっくり原因

"q" <- メモリ上の何処かに確保された{'q','\0'}というデータの先頭アドレス
line<- メモリ上の何処かに確保された要素数256個のchar配列の先頭アドレス

line != "q" <- 等しいはずがないので常に真


ざっくり対処法

C言語 文字列 比較でググる。
するとstrcmpとか見つかるので頑張る。

投稿2016/11/09 03:18

ozwk

総合スコア13512

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

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

0

ベストアンサー

whileの終了条件で line != "q" とされてますが、これではline[256] の領域の先頭アドレス と "q"の先頭アドレスを比較しているため常に真となります。

文字列の比較には strcmp() 関数を使用してください。

#課題かなにかのようですので助言だけ

投稿2016/11/09 03:16

編集2016/11/09 03:43
Y.H.

総合スコア7914

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

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

yusukee345

2016/11/09 03:44

#include<stdio.h> #include<stdlib.h> #include<string.h> #pragma warning(disable:4996) #define size 1024 void main(){ FILE* file; char line[size]; line[0] = '\0'; file = fopen("c:\\test\\data.txt","w"); if (file == NULL){ printf("ファイルが開けません\n"); exit(1); } do{ printf("文字列を入力してください:"); scanf("%s", line); fprintf(file, "%s\n", line); } while (strcmp(line, "q") != 0); fclose(file); file = fopen("c:\\test\\data.txt","r"); if (file == NULL){ printf("ファイルが開けません\n"); exit(1); } while (fgets(line, size, file) != NULL){ printf("%s ",line); } getchar(); } で出来ました。すごい初歩的な所で躓いていました。お陰様で文字列比較を思い出せてありがとうございます。
guest

0

全体的に見直すべき箇所はあります、、、がそこはおいといて、質問のq入力の部分ですが。

line != "q"

という比較はできません。
char配列で宣言したlineは
line[0]などには目的とする文字が入っていますが、lineとしてしまうとそこにはアドレスが入っていますので
この条件はアドレスと文字qを比較している事になります。

投稿2016/11/09 03:15

hiim

総合スコア1689

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

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

0

これでできると思います

c

1#include<stdio.h> 2 3#include<stdlib.h> 4 5 6#define size 256; 7 8void main(){ 9FILE *file; 10char line[256]; 11 12 13line[0] = '\0'; 14file = fopen("c:\\test\\data.txt","w"); 15if (file == NULL){ 16printf("ファイルが開けません\n"); 17exit(1); 18} 19do{ 20printf("文字列を入力してください:"); 21scanf("%s", line); 22fprintf(file, "%s", line); 23}while(line[0] != 'q'); 24fclose(file); 25file = fopen("c:\\test\\data.txt","r"); 26if (file == NULL){ 27printf("ファイルが開けません\n"); 28exit(1); 29} 30while (fgets(line,256,file) != NULL){ 31printf("%s ",line); 32} 33fclose(file); 34getchar(); 35}

投稿2016/11/09 03:39

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

修正を加えてみました 
但しqで抜けるところのみです。ファイルへの書込部分はそのまま

c

1#include<stdio.h> 2#include<stdlib.h> 3#include<string.h> 4#pragma warning(disable:4996) 5#define size 256 6 7 void main(){ 8 FILE* file; 9 char line[256]; 10 line[0] = '\0'; 11 file = fopen("c:\\test\\data.txt","w"); 12 if (file == NULL){ 13 printf("ファイルが開けません\n"); 14 exit(1); 15 } 16 do{ 17 printf("文字列を入力してください:"); 18 scanf("%s", line); 19 fprintf(file, "%s", line); 20 }while(!(line[0] == 'q' && strlen(line) == 1)); 21 fclose(file); 22 file = fopen("c:\\test\\data.txt","r"); 23 if (file == NULL){ 24 printf("ファイルが開けません\n"); 25 exit(1); 26 } 27 while (fgets(line, size, file) != NULL){ 28 printf("%s ",line); 29 } 30 getchar(); 31 }

投稿2016/11/09 03:37

編集2016/11/09 03:40
A.Ichi

総合スコア4070

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問