3

C を使用して文字列 (*char) を連結しようとすると、多くのセグメンテーション エラーが発生します。

void printDateFormat( char *in ) { /* begin function printDateFormat */

   char *month;          // month by char
   int month_int;        // month by digit
   char *day;            // day by char
   char *year;           // year by char
   char *dateToken;      // date token in split
   char *formatted;      // formatted string

   dateToken = strtok (in, "/");
   month = &dateToken;

   formatted = formatted = getMonth(month);

   dateToken = strtok (NULL, "/");
   day = &dateToken;

   formatted = strcat (formatted, day);
   formatted = strcat (formatted, ", ");

   dateToken = strtok (NULL, "/");
   year = &dateToken;

   formatted = strcat (formatted, year);

   in = *formatted;

} /* End function printDateFormat */


char *getMonth( int d) { /* begin function *getMonth */

switch (d) {

  case 1:
     return "January";
 //    break;
  case 2:
     return "February";
 //    break;
  case 3:
     return "March";
 //    break;
  case 4:
     return "April";
//     break;
  case 5:
     return "May";
//     break;
  case 6:
     return "June";
//     break;
  case 7:
     return "July";
//     break;
  case 8:
     return "August";
//     break;
  case 9:
     return "September";
//     break;
  case 10:
     return "October";
 //    break;
  case 11:
     return "November";
//     break;
  case 12:
     return "December";
//     break;
   }

} /* End function *getMonth */

printDateFormat() への入力は、次の形式の別の文字列として期待されます: MM/dd/yyyy ... つまり。2013 年 3 月 31 日。目的は、それを 2013 年 3 月 31 日にすることです。

編集:

これが私が渡す方法ですprintDateFormat

void option1( void ) { /* begin function option1 */

    char date[10]; /*user input date string */

    printf("\n\nEnter date [Format: MM/dd/yyyy]: ");
    fgets(date, 10, stdin);

    scanf("%s", &date);

    printDateFormat(date);

    printf("\n%s", date);

} /* End function option2 */

編集2:

わかりました、いくつかの変更を加えましたが、まだダイスはありません...

ここに私のコンパイラの警告があります:

asgn9.c: In function `printDateFormat':
asgn9.c:224: warning: passing arg 1 of `getMonth' makes integer from pointer without a cast
asgn9.c:237: warning: assignment makes pointer from integer without a cast

getMonth()彼らは私の中での使用を指しますprintDateFormat()

これが私の更新されたコードです。同じ場所でまだセグメンテーション違反が発生しています...

void printDateFormat( char *in ) { /* begin function printDateFormat */

    char *month;          // month by char
    int month_int;        // month by digit
    char *day;            // day by char
    char *year;           // year by char
    char *dateTkn;      // date token in split
    char *formatted;      // formatted string

    dateTkn = strtok (in, "/");
    month = dateTkn;

    formatted = getMonth(month);

    dateTkn = strtok (NULL, "/");
    day = dateTkn;

    formatted = strcat (formatted, day);
    formatted = strcat (formatted, ", ");

    dateTkn = strtok (NULL, "/");
    year = dateTkn;

    formatted = strcat (formatted, year);

    in = *formatted;

} /* End function printDateFormat */

char *getMonth( int d) { /* begin function *getMonth */

    static char *months[] = {"January", "February", "March", "April", "May",
        "June", "July", "August", "September", "October", "November", "December"};

    return strcpy(malloc(32), months[d]);

} /* End function *getMonth */
4

6 に答える 6

4

あなたgetMonthは文字列リテラルへのポインタを返します。それを変更しようとする試み (たとえば、 を使用strcat) は許可されていません。未定義の動作につながります。

strftime印刷用の日付および/または時刻文字列の書式設定を処理するために使用することを (強く) 提案します。これにより、書式設定コードが 1 行に削減されるだけでなく、必要に応じてローカライズされた結果をサポートすることもできます。

編集: を使用できない場合はstrftime、おそらく次を使用して、独自のバッファーにフォーマットされた日付を作成する必要がありますsprintf

char buffer[256];
static const char *months[] = {
    "January", 
    "February", 
    /* ... */ , 
    "November", 
    "December"
};

sprintf(buffer, "%s %d %d", months[monthnum], day, year);
于 2013-04-01T03:05:03.570 に答える
1

問題のいくつかを解決し、コードを簡素化できます。

char *getMonth(int d) {
  static char *months[] = { "January", "February", "March",
    . . .
  };

  return strcpy(malloc(60), months[d]);
}

こちらです、

  • 戻り値は書き込み可能です
  • strcat() ops 用の追加スペースがあります

産業用強度については、 の戻り値をチェックしたり、が範囲内にあるmalloc()かどうかなどを確認したい場合があります。n

于 2013-04-01T03:14:40.480 に答える
1

によって返される値

getMonth(month);

定数文字列へのポイントです。strcat() を含め、この文字列は変更できません。次のように、要件を満たすように関数を変更できます。

char formatted[MAXSIZE];      // formatted string
getMonth(month, formatted);

void getMonth( int d, char *cache) { /* begin function *getMonth */
    switch (d) {
        case 1:
            strcpy(cache, "January");
            return;
        ......
}

その後、「フォーマット済み」の char 配列のコンテンツを引き続き変更できます。

于 2013-04-01T03:05:18.427 に答える
1

フォーマット済みのメモリが割り当てられていません。Formatted の宣言を次のように変更します。

char formatted[80];

最初の割り当てをフォーマット済みに変更します

strcpy ( formatted, getMonth ( month ), sizeof ( getMonth ( month ) ) );

そして、あなたは大丈夫なはずです。

于 2013-04-01T03:05:52.213 に答える
1

あなたの投稿が正しいと仮定すると、問題は

month = &dateToken;
....
day = &dateToken;
....
year = &dateToken;

strtok は char * を返すので、各「dateToken」から & を削除するだけです。また、「getMonth」入力のプロトタイプは「int」型ですが、関数に「char *」型を指定すると、「switch」テーブルは数字以外のテーブルケースを認識しません。

于 2013-04-01T03:06:17.263 に答える
1

C は文字列処理用の言語ではありません。可能であれば、C++ と std::string を使用してください。

C でこれを行う 1 つの方法はchar buffer[BUFFERSIZE]、2 つの文字列を連結するために大きなバッファーを定義して、2 つの文字列をコピーすることです。バッファをオーバーランしないように注意してください!

バッファーを malloc/free することもできますが、それは別の頭痛の種です。

于 2013-04-01T03:08:46.323 に答える