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来处理格式化日期和/或时间字符串以进行打印。这不仅可以将您的格式化代码简化为单行代码,还可以让您在需要时/如果需要也支持本地化结果。

编辑:如果你不能使用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

返回的值由

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;
        ......
}

之后,您可以继续修改“格式化”字符数组中的内容。

于 2013-04-01T03:05:18.427 回答
1

您还没有为格式化分配任何内存。将格式化的声明更改为

char formatted[80];

并将第一个作业更改为格式化为

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

你应该没事。

于 2013-04-01T03:05:52.213 回答
1

假设您的帖子是正确的,那么问题是

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

strtok return char *,所以只需从每个“dateToken”中删除 &。而你的'getMonth'输入原型是'int'类型,但是你给的函数是'char *'类型,'switch'表不会识别非数字表的情况。

于 2013-04-01T03:06:17.263 回答
1

C 不是用于字符串处理的语言。如果可能,请使用 C++ 和 std::string。

在 C 中执行此操作的一种方法是定义一个大char buffer[BUFFERSIZE]缓冲区以将两个字符串复制到其中以连接它们。小心不要超出缓冲区!

您还可以 malloc/free 缓冲区,但这是另一个令人头疼的问题。

于 2013-04-01T03:08:46.323 回答
1

您可以通过以下方式解决一些问题并简化代码:

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

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

这边走,

  • 返回值是可写的
  • 它为您的 strcat() 操作提供了额外的空间

对于工业强度,您可能需要检查 的返回值malloc(),查看是否n在范围内,诸如此类。

于 2013-04-01T03:14:40.480 回答