• ベストアンサー

春期の基本情報技術者試験の問題について

基本情報試験の勉強の為に過去門を解いていたのですが 自分には分からない記述があったので質問しました 下記のプログラムの while(bp > base && *--bp != '/'); とは一体どのような処理をしているのか教えてください C言語は独学で勉強したのですがこのようなwhile文の 使用方法はどこにものっていなかったので・・・ よろしくお願いします。 問題は平成21年春期の基本情報技術者試験の 午後の問9です。 #include <string.h> void convert(const char*, const char*, char*); void convert(const char *path, const char *base, char *result){ const char *pp, *bp; char *rp; int length; /* pathが絶対パス表記の場合 */ if(*path == '/'){ ; return; } /* pathがカレントディレクトリの場合 */ if(!strcmp(path, ".") || !strcmp(path, "./")){ ; return; } length = strlen(base); bp = base + length; /* bpは文字列baseの終端を指す。*/ if(*(bp - 1) == '/') --bp; /* pathの先頭部にある".."又は"../"を解析することで, baseのパス表記のうち,どこまでresultと共通になるかを調べる。*/ for(pp = path; *pp != '\0' && *pp == '.';){ if(!strncmp(pp, "../", 3)){ pp += 3; while(bp > base && *--bp != '/'); }else if(!strncmp(pp, "./", 2)){ pp += 2; }else if(!strncmp(pp, "..\0", 3)){ pp += 2; while(bp > base && *--bp != '/'); }else{ break; } } /* baseのパス表記と共通な部分をresultに複写する。*/ length = ; strncpy(result, base, length); rp = ; *rp++ = '/'; /* pathの文字列のうち,先頭部分の"./"や".."を除いた残りの 部分(ppが指す文字列)を,resultの文字列に追加する。 */ strcpy(rp, pp); return; }

質問者が選んだベストアンサー

  • ベストアンサー
  • jppy
  • ベストアンサー率14% (14/99)
回答No.1

まず int i=1000; /* int型のiの初期化 */ while(--i); /* iをデクリメントしてi=0(whileの判断が偽になったらループを抜ける) */ これはOK? んで質問は  while(bp > base && *--bp != '/'); ですね  1.bp:ポインタですね  2.*--bp:これでポインタを移動させています。  3.bpをずらしながら、      bp > base (先頭を超えない)      かつ      *--bp != '/' (後ろから「/」がでるまで)    の条件が破たんするのを待っています  4.while配下に処理なしです じゃあ何がしたいのかということですが、   bpを移動したかったということが目的となります

gowogowo
質問者

お礼

回答ありがとうございます。 この場合while文の条件式の中でbpの値を 減算しているってことですよね?

その他の回答 (1)

  • goosyu
  • ベストアンサー率58% (36/62)
回答No.2

秋の「基本情報技術者試験」受験されるのでしょうか,がんばって下さい。 本題 私は「while(bp > base && *--bp != '/');」を次の様に考えました。 // ループを抜ける条件に変換してみます。 while(1) { // 「(bp > base && *--bp != '/')」をNOTしてループ終了条件にする // if (bp <= base || *--bp == '/') break; // || でif文を分けます。 if (bp <= base) break; --bp; if (*bp == '/') break; }

関連するQ&A

  • ================

    ================ for(pp = path; *pp != '\0' && *pp == '.';){ if(!strncmp(pp, "../", 3)){ pp += 3; while(bp > base && *--bp != '/'); } ================ http://xn--n9q36mh1hnxuksz7wt.jp/FE21a-pm/t09.html この処理について教えてください。 if文の実行条件がどうしても分からないのです。 !strncmp(pp, "../", 3)はppの要素の先頭3文字と"../"の先頭3文字を比較して 一致しなかった場合にpp += 3;とwhile文を実行すると解釈しています。 つまり、ppの要素の先頭3文字が"../"だった場合は一致するのでif文は 実行されないと思うのですが、解説をみると逆になっています。 (ppの要素の先頭3文字が"../"だった場合は一致するのでif文は実行される。) http://www.kmctec.net/k_gogo/gogo11/gogoans1144.PDF if(!strncmp(pp, "../", 3))をどのように解釈すればいいのでしょうか?

  • strtol関数をmalloc()関数を使用して次のソースプログラムを

    strtol関数をmalloc()関数を使用して次のソースプログラムを修正しなさいを言われました。 どなたか詳しい方よろしくお願いします。 #include <limits.h> #include <ctype.h> #include <errno.h> #include <stdio.h> int _space_sign(const char *s, const char **endptr); int _space_sign(const char *s, const char **endptr) { int sign ; while (isspace((unsigned char)*s)) ++s; sign = 0; switch (*s) { case '-': sign = -1; // fall through case '+': ++s; break; } *endptr = s; return sign; } long int strtolong(const char * s, char ** endptr, int base) { int c; int sign = _space_sign(s, (const char**)&s); long result; if (s[0] == '0') { ++s; if ((s[1] | 0x20) == 'x') { if (base == 0 || base == 16) { ++s; base = 16; } } else if (base == 0) base = 8; } else if (base == 0) base = 10; result = 0; for (; c = tolower((unsigned char)*s), isdigit(c) || ('a' <= c && c <= 'v'); s++) { int d ; if( isdigit(c) ) d= c - '0' ; else d = c - 'a' + 10; if (d >= base) break; if (result > (LONG_MAX - d - sign) / base) { errno = ERANGE; result = sign ? LONG_MIN : LONG_MAX; } else { result = result * base + d; } } if (endptr != NULL) *endptr = (char*)s; if (sign != 0) result = -result; return result; } int main(void) { char s[128], *e; long n; int base; printf("何進数で変換しますか。"); scanf("%d", &base); printf("変換する数値を入力してください。"); scanf("%s", s); n = strtolong(s, &e, base); if (errno != ERANGE) { printf("変換数値=%ld\n", n); if (*e != '\0') { printf("変換不可能部分=%s\n", e); printf("%d文字目の\'%c\'が変換不可\n", e-s+1, *e); } } else if (n == LONG_MAX) printf("long値で表現できる値を上回りました。\n"); else if (n == LONG_MIN) printf("long値で表現できる値を下回りました。\n"); return 0; }

  • H21年春期基本情報技術者午後問11(JAVA)

    H21年春期基本情報技術者午後問11(JAVA)で、 [プログラム2]の 引数textに格納される物が分かりません。 分かる方、教えて下さい。 //プログラム1 class GapBuffer { private static final int INITIAL_GAP_SIZE = 128; private char[] buffer; private int gapOffset = 0; private int gapSize = INITIAL_GAP_SIZE; GapBuffer(String initialText){ buffer = new char[initialText.length() + gapSize]; System.arraycopy(initialText.toCharArray(), 0, buffer, gapSize, initialText.length()); } void insert(int offset, char ch) { confirmGap(offset); buffer[gapOffset++] = ch; gapSize--; } void delete(int offset){ if (length() == 0) return; confirmGap(offset + 1); gapOffset--; gapSize++; } char charAt(int offset) { if (offset >= gapOffset) offset += gapSize; return buffer[offset]; } int length() { return buffer.length - gapSize ;} private void confirmGap(int newGapOffset){ if (gapSize == 0) { char[] temp = new char[buffer.length + INITIAL_GAP_SIZE]; System.arraycopy(buffer, 0, temp, 0, buffer.length); gapOffset = buffer.length; gapSize = INITIAL_GAP_SIZE; buffer = temp; } if(newGapOffset < gapOffset) { System.arraycopy(buffer, newGapOffset, buffer, newGapOffset + gapSize, gapOffset - newGapOffset); } else { System.arraycopy(buffer, gapOffset + gapSize, buffer, gapOffset, newGapOffset - gapOffset); } gapOffset = newGapOffset; } } /プログラム2 class Editor { private GapBuffer buf; private int cursor = 0; private Editor(String text) { buf = new GapBuffer(text);←此処です } private void run() { Display.output(buf, cursor); char ch; while ((ch = CharReader.get()) != CharReader.EOF) { switch (ch){ case CharReader.MOVE_FORWARD: moveCursor(1); break; case CharReader.MOVE_BACKWARD: moveCursor(-1); break; case CharReader.DELITE: if (cursor < buf.length()) { buf.delete(cursor); } break; default: buf.insert(cursor++, ch); break; } Display.output(buf, cursor); } } private void moveCursor(int n) { int newCursor = cursor + n; if (newCursor >= 0 && newCursor <= buf.length()) { cursor = newCursor; } } public static void main(String[] args) { Editor editor = new Editor(args[0]); editor.run(); } }

  • c言語関数の(1)~(5)までの部分が何をやっているのかよく分からない

    c言語関数の(1)~(5)までの部分が何をやっているのかよく分からないので、どなたか解説をお願いします。 int memcmp(const void *s1, const void *s2, size_t n) { const unsigned char *p1 = (const unsigned char *)s1; const unsigned char *p2 = (const unsigned char *)s2; while (n-- > 0) { if (*p1 != *p2) return (*p1 - *p2); p1++; p2++; } return (0); } return (*p1 - *p2); > (1) ---------------------------------------------------------------------- char *strcat(char *s1, const char *s2) { char *p = s1; while (*s1) s1++; /* s1を末尾まで進める */ while (*s1++ = *s2++) ; /* '\0'が見つかるまでs2をコピー */ return (p); } while (*s1++ = *s2++) ; > (2) ---------------------------------------------------------------------- char *strstr(const char *s1, const char *s2) { const char *p1 = s1; const char *p2 = s2; while (*p1 && *p2) { if (*p1 == *p2) { p1++; p2++; } else { p1 -= p2 - s2 - 1; p2 = s2; } } return (*p2 ? NULL : (char *)(p1 - (p2 - s2))); } while (*p1 && *p2) > (3) p1 -= p2 - s2 - 1; > (4) ---------------------------------------------------------------------- char *strcpy(char *s1, const char *s2) { char *p = s1; while (*s1++ = *s2++) ; return (p); } while (*s1++ = *s2++)   > (5) ;          > (5) ----------------------------------------------------------------------

  • 前回質問させて頂き、改善できるところはしました。

    前回質問させて頂き、改善できるところはしました。 再度駄目な所をご指摘お願いします。 仕様は出来るだけ標準関数に近いものを自作したいと思っています。 //---------------------------- MyStrstr ----------------------------------// char *MyStrstr(const char *str1, const char *str2) { const char *p1 = str1; const char *p3 = str1; const char *p2 = str2; while(*p1 != *p2 && *p1 && *p2) { *p1++; *p3++; } while(*p1 == *p2){ *p1++; *p2++; } return (*p2 ? NULL : (char*)p3); } //------------------------------ 終了 ------------------------------------// //---------------------------- MyStrcat ----------------------------------// char *MyStrcat(char *str1, const char *str2) { char *p1 = str1; const char *p2 = str2; while(*p1 != NULL){ p1++; } if(*p2){ while(*p2 != NULL){ *p1 = *p2; p1++; p2++; } } if(*p2 == NULL){ *p1 = *p2; } return p1; } //------------------------------ 終了 ------------------------------------// //---------------------------- MyStrcmp ----------------------------------// int MyStrcmp(const char *str1, const char *str2) { const char *p1 = str1; const char *p2 = str2; while(*p1 != NULL || *p2 != NULL){ if(*p1 == *p2){ p1++; p2++; }else{ if(*p1 < *p2) return -1; if(*p1 > *p2) return 1; } } return 0; } //------------------------------ 終了 ------------------------------------// //----------------------------- MyMemcpy -----------------------------------// void *MyMemcpy(void *str1, void *str2, size_t n) { char *p1 = (char*)str1; char *p2 = (char*)str2; while(n--){ *p1 = *p2; p1++; p2++; } return str1; } //------------------------------ 終了 ------------------------------------// //---------------------------- MyStrcpy ----------------------------------// char *MyStrcpy(char *str1, const char *str2) { char *p1 = str1; const char *p2 = str2; while( *p2 != NULL){ *p1 = *p2; p1++; p2++; } if(*p2 == NULL){ *p1 = *p2; } return p1; } //------------------------------ 終了 ------------------------------------// //---------------------------- MyMe

  • memcpy,memcmp,strcmp,strlen,strcat,

    memcpy,memcmp,strcmp,strlen,strcat,strcpy,strstr,strchr 以上の関数を自作しました。 ひとつひとつを見たときに動作を確認したところうまく出来たのですが、この関数をプログラムに組み込んだところうまく動作しませんでした。 どこか間違っているところがあったら指摘して頂きたいと思います<m(__)m> ちなみに標準関数と全く同じものにしたいわけではなく、それを自分なりに考えて作りたいという趣旨ですので、ご理解ください。 char *MyMemcpy(char *str1, char *str2, size_t n) { char *p1 = str1; char *p2 = str2; while(n--){ *p1 = *p2; p1++; p2++; } return str1; } void *MyMemcmp(void *str1, void *str2) { char *p1 = (char*)str1; char *p2 = (char*)str2; int n = 0, k = 0; while( *p1 != '\0'){ *p1++; n++; } while( *p2 != '\0'){ *p2++; k++; } if(n > k){ return str1; }else if(n == k){ return 0; }else if(n < k){ return str2; } } char *MyStrcmp(char *str1, char *str2) { char *p1 = str1; char *p2 = str2; int n = 0, k = 0; while( *p1 != '\0'){ *p1++; n++; } while( *p2 != '\0'){ *p2++; k++; } if(n > k){ return str1; }else if(n == k){ return 0; }else if(n < k){ return str2; } } size_t MyStrlen(const char *str1) { char *p1 = (char*)str1; size_t len = 0; while(*p1 != NULL){ *p1++; len++; } return len; } char *MyStrcat(char *str1, const char *str2) { char *p1 = str1; char *p2 = (char*)str2; while(*p1 != NULL){ *p1++; } while(*p2 != NULL){ *p1 = *p2; *p1++; *p2++; } return str1; } char *MyStrcpy(char *str1, char *str2) { char *p1 = str1; char *p2 = str2; while( *p2 != NULL){ *p1 = *p2; *p1++; *p2++; } *p1 = '\0'; return str1; } char *MyStrstr(char *str1, char *str2) { char *p1 = str1; char *p2 = str2; while(*p1 != *p2) { if(*p1 == '\0'){ return 0; } *p1++; } return p1; } char *MyStrchr(const char *str1, char str2) { char *p1 = (char*)str1; while(*p1 != str2) { if(*p1 == '\0'){ return 0; } *p1++; } return p1; }

  • C言語

    文字列を逆順にするプログラムを考えているのですが分かりません。(例)qwerならrewqです。入力終了は、EOFです。考えたのですが、分かりません。(コンパイルエラーです。)教えてください。宜しくお願いします。#include <stdio.h> unsigned str_length(const char str[]) { unsigned len=0; while (str[len]) len++; return (len); } void put_rstring(const char str[]) { unsigned i = str_length(str): while (i-- >0) putchar(str[i]); } int main(void) { char str[30]; int ch; printf("文字列を入力\n"); /* ----この文字列を入力したあとに、Ctrl+Zを押すと、逆から表示               で反対から、文字列が表示----*/ while (1) { ch=getchar(); if (ch==EOF) break; } printf("逆から表示"); put_rstring(str); puts("です。"); return(0); }

  • bsearch関数の内容について

    stdlib関数のbsearch関数で、次のことを教えてください。 void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { size_t pl = 0; /* 探索範囲先頭の添字 */ size_t pr = nmemb - 1;/* 探索範囲末尾の添字 */ char *x = (char *)base;/*なぜchar *にキャスト?*/ if (nmemb > 0) { while (1) { size_t pc = (pl + pr) / 2;/* 探索範囲中央の添字 */ int comp = compar((const void *)&x[pc * size], key); ~~~~~~~~~~~~~~~~~~~~~~~~~~~ /*なぜsizeを掛けるのか?*/ if (comp == 0) /* 探索成功 */ return (&x[pc * size]); else if (pl == pr) break; else if (comp < 0) pl = pc + 1;/* 探索範囲を後半に絞り込む */ else pr = pc - 1;/* 探索範囲を前半に絞り込む */ } } return (NULL);/* 探索失敗 */ }

  • 関数について

    char *str_char(const char *str, int c) { while (*str++) if (*str == c) return ((char *)str); return (NULL); } /*文字列strから文字cを検索し最初に存在する文字へのポインターを返す*/ 上記関数なのですが 5行目を return (str); にしてはなぜいけないのでしょうか。

  • このプログラムは「こんにちは」と打つと「こんにちは、元気ですか」と返答

    このプログラムは「こんにちは」と打つと「こんにちは、元気ですか」と返答するプログラムです このプログラムを改良して「こんにちは」と打つと「こんにちは、元気ですか」と言うようなキーワードを打つ決められた回答をするようなものを増やしていきたいのですが、どのように改良すればよいでしょうか? 例えば 「寒いですね」といれると「冬だからね」となるように #include <stdio.h> #include <string.h> int reply(const char *s) { const char *reply_s[] = {"こんにちは 元気ですか?", "バイバイ", "ふ~ん?"}; if(strstr(s, "こんにちは")) puts(reply_s[0]); else if(strstr(s, "さようなら")){ puts(reply_s[1]); return 0; } else puts(reply_s[2]); return 1; } int main(void) { char s[128]; do{ char *p; fgets(s, sizeof s, stdin); if(p = strchr(s, '\n')) *p = '\0'; }while(reply(s)); return 0; }

専門家に質問してみよう