#include<stdio.h>
#include<string.h>

int main (void){
char str [] = "onetwothreefourfivesix";
char buf[100];
char *p, *q;
int i,count;
strncpy(buf,&str[2],3);
buf[2] = '\0';
strcat(buf,&str[16]);
printf("%s\n",buf);

buf[0] = '\0';
for( i = 0; i < 3; i++){
strncat(buf, str + i *3, 3);
strcat(buf,",");
}
printf("%s\n",buf);

strcpy(buf,str);
p = strrchr(buf,buf[0]);
*p = '\0';
printf("%ld\n",strlen(buf));

count = 0;
for (p = str; *p != '\0' ;p++){
if(*p == 't' || *p == 'e'){
count++;
}
}
printf("%d\n",count);

i = 0;
p = str;
q - str + strlen(str) - 1;

while(p < q){
if(i % 2 == 0)
buf[i] = *p;
}else{
buf[i] = *q;
}
p += 3;
q -= 2;
i++;
}
buf[i] = '\0';
printf("%s\n",buf);   //ここのbufがどう表示されるのか解説をお願いします。
return0;
}

A 回答 (2件)

まず、ソースがエラーになりましたので、ソースを修正しました。


修正した箇所は、//修正①②③です。
又、1行追加しました。//追加④です。
以下のようになります。
---------------------------------------------
#include<stdio.h>
#include<string.h>

int main (void){
char str [] = "onetwothreefourfivesix";
char buf[100];
char *p, *q;
int i,count;
strncpy(buf,&str[2],3);
buf[2] = '\0';
strcat(buf,&str[16]);
printf("%s\n",buf);

buf[0] = '\0';
for( i = 0; i < 3; i++){
strncat(buf, str + i *3, 3);
strcat(buf,",");
}
printf("%s\n",buf);

strcpy(buf,str);
p = strrchr(buf,buf[0]);
*p = '\0';
printf("%ld\n",strlen(buf));

count = 0;
for (p = str; *p != '\0' ;p++){
if(*p == 't' || *p == 'e'){
count++;
}
}
printf("%d\n",count);

i = 0;
p = str;
q = str + strlen(str) - 1; //修正①
printf("<%c>\n",*q); //追加④
while(p < q){
if(i % 2 == 0){ //修正②
buf[i] = *p;
}else{
buf[i] = *q;
}
p += 3;
q -= 2;
i++;
}
buf[i] = '\0';
printf("%s\n",buf);//ここのbufがどう表示されるのか解説をお願いします。
return 0; //修正③
}
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
この実行結果ですが、以下のようになります。
etivesix
one,two,thr,
12
6
<x>
ostfo
-------------------------------
ここで、<x>は//追加④で出力された内容、
ostfoはbufの内容です。
従って、buffの内容がostfoであることの説明ができれば、それが求める答えです。
以下、その説明です。
------------------------------------------------
pはstr[]の先頭位置の為、oの位置になります。
qは、str[]の先頭位置に文字列の長さを加え、-1するので最後の文字であるxの位置になります。
④で*qの内容を印字するとxであることが確認できます。

while(p<q){
}
の処理では、以下の処理を行っています。
1)0,2,4...回目(偶数回目)は、pの値をbufに格納(最初は0回目とします)
2)1,3,5...回目(奇数回目)は、rの値をbufに格納
3)回数が1回増えるごとに、pは3バイト追加されます。
従って、o,t,t,e,o,f・・・と増えます。このうち採用されるのは、偶数回目なので、o,t,oです。
4)回数が1回増えるごとに、qは2バイト減算追加されます。
従って、x,s,v,f,u,f・・・と減っていきます。このうち採用されるのは、奇数回目なので、s,f,fです。
5)3)と4)から取り出される文字を取り出し順に並べると
ostfofとなります。
ここで、p<qの条件の間の取り出しなので、
ostfoとなります。
    • good
    • 0
この回答へのお礼

お返事遅れまして失礼しました。

ようやく飲み込めた気がします。。

色々とありがとうございました。

お礼日時:2017/05/14 23:17

処理系とOS,ハードウエア依存ですからこれだけではどう表示されるかは不確定です。

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aと関連する良く見られている質問

Qerror C2143: 構文エラー : ';' が '{' の前にありません。

#include <stdio.h>
int main(void)
{
  int in;
  printf("20以上の数字を入力してください\n");
  scanf("%d", &in);

  if(in >= 20){
    printf("20以上の数字です。\n");
    printf("終了します\n\n");}

  else if(in <= 5){
    printf("5以下の数字が入力されました\n");
    printf("20には程遠いです\n\n");}

  else(in <= 19){
    printf("20以上の数字ではありません\n");
    printf("20以上の数字を入力してください\n\n");}
  return 0;
}

C言語でVisual C++ Expressを使っています
このコードでビルドすると
(16) : error C2143: 構文エラー : ';' が '{' の前にありません。
と表示されてしまいます。何がいけないのでしょうか?

#include <stdio.h>
int main(void)
{
  int in;
  printf("20以上の数字を入力してください\n");
  scanf("%d", &in);

  if(in >= 20){
    printf("20以上の数字です。\n");
    printf("終了します\n\n");}

  else if(in <= 5){
    printf("5以下の数字が入力されました\n");
    printf("20には程遠いです\n\n");}

  else(in <= 19){
    printf("20以上の数字ではありません\n");
    printf("20以上の数字を入力してください\n\n");}
  return...続きを読む

Aベストアンサー

  else(in <= 19){
の部分ですが、
  else if (in <= 19){
のつもりだったのでしょうか。
この場合、
  else{
だけでよいです。

Qint i,j; \n i=0,j=5;

int i,j;
i=0;
j=5:
と書いてあるソースは普通ですが、
int i,j;
i=0,j=5:
と書いてあるソースもあります。
後者はC++の正しい書式ですか?

カンマ演算子というのは後者のカンマのことですか?

Aベストアンサー

 正しい書式です。

i=0,j=5;
 における、「,」をカンマ演算子といいます。2項の演算子です。カンマで区切られた演算を「左から順番に」実行し、最後の演算を結果として返します。
 したがって、例の文であれば、i=0を実行し、次にj=5を実行。そして、j=5の結果の5を結果として返します。
 ・・・
 が、本来的には、あまり、例のような使い方はしませんね。よく見られるのは、次のような場合です。

 for (i=0,j=0 ; i < 50 ; ++i,++j) {

 のような形でよく見られます。for文の各式は、一つの式でなければならないので、こんな書き方をするわけです。初期化と更新部が一つにまとまり、ループが読みやすくなるのが利点かな。

Qchar *str; と char* str;

char *str; と char* str;
どっちも同じことを意味しているんですか?

Aベストアンサー

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染むのでしょう。ちなみにそういう風な人たちは

char *str1, *str2;

とは、書けない体になっています。

char* str1;
char* str2;


変数の宣言だと、C に慣れていれば、char* str というのはちょっと違和感があるのは
私も分かりますが、関数のプロトタイプ宣言だと、どちらの方がすっきりしますか?

extern char *memcpy(char *, const char *);

extern char* memcpy(char*, const char*);


# まあ、どっちが正しい、っていうんじゃ無いんですよね

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染む...続きを読む

Qdc.TextOut(0 ,0 , *str) ;について

環境 WIN98 VC++6.0 MFC にて

パターンBはOKですが、パターンAだと不正な処理で落ちてしまいます。

どうしてなのかお教えください。

void CFffView::OnPaint()
{
CPaintDC dc(this);
//パターンA
CString* str ;
str = (CString*)("999");
dc.TextOut(0 ,0 , *str) ;

//パターンB
CString aaa ;
aaa = (CString)("999");
dc.TextOut(0 ,0 , aaa) ;
}

Aベストアンサー

両方ダメ。
Aのパターンで動くのは、たまたま。

CString aaa ;
aaa = "999";
dc.TextOut(0 ,0 , aaa) ;

これで十分。

あえてキャストするんだったら、
CString aaa ;
aaa = (LPCSTR)"999";
dc.TextOut(0 ,0 , aaa) ;


aaa=のところでは、ただの代入が行われているわけではありません。
オーバーロードされたオペレータが呼ばれています。


>str = (CString*)m_array.GetAt(i) ;

これは、m_arrayの要素にCString*を入れていて、初めて成り立つ式です。
値をいれているところと、m_arrayの宣言を確認してください。

str = (CString*)("999");
も、
aaa = (CString)("999");
も、リテラル文字列をつっこもうとしています。
リテラル文字列とCStringはまったく別物です。

Qtry{}catch(){}とデストラクタの関係を教えてください。

try-catchでメモリ確保を含むクラスをスローした場合、デストラクタはどの時点で働くのか、教えてください。たとえば、↓の使いかたは大丈夫でしょうか?

【1】
try{
 throw(CError(100, "エラー情報"));
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
}

【2】
try{
 CError err(100, "エラー情報");
 throw(err); // (1)
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
 //まだデストラクタはちゃんと動作するのでしょうか?
 //catchが呼び出し元のメンバであったりしても大丈夫なのでしょうか?
}

宜しくお願いします。

Aベストアンサー

【1】【2】どちらの場合も問題がありません。
コンパイラが必要に応じてerrオブジェクトのコピーを作成します。
デストラクタが呼び出されるタイミングはコンパイラに依存するところもあると思いますが、
例えばVC7.1では【2】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) CErrorクラスのテンポラリオブジェクト(以下a)のコピーコンストラクタが呼び出される。
(3) errオブジェクトのデストラクタが呼び出される
(4) catch文まで到達
(5) aオブジェクトのデストラクタが呼び出される。

VC7.1では、【1】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) catch文まで到達
(3) errオブジェクトのデストラクタが呼び出される。

コンパイラがオブジェクトのコピーを省略しているようです。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報