2013-04-01 3 views
3

Попытка Concat строки (* полукокс) с использованием C и имеющей много ошибок сегментации:C - Concat Строка

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(), как ожидается, в качестве другой строки в формате: дд/мм/yyyy ... т.е. 03/31/2013. Цель состоит в свою очередь, что в: 31 марта 2013 г.

EDIT:

Вот как я прохожу в 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 */ 

EDIT 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 */ 
+1

Что вы передаете 'printDateFormat'? – dasblinkenlight

+0

@dasblinkenlight см. Править. – SnakeDoc

+1

Вам не нужен амперсанд в 'scanf («% s », &/* << == Here */date);' это так же хорошо, как 'scanf («% s », дата);' – dasblinkenlight

ответ

4

Вашего getMonth возвращает указатель на строковый литерал. Попытка изменить его (например, с помощью strcat) не допускается - это приводит к неопределенному поведению.

Я бы (настоятельно) предложил использовать strftime для обработки даты форматирования и/или временных строк для печати. Это не только уменьшит ваш код форматирования до однострочного, но также позволит вам поддерживать локализованные результаты, когда вы захотите.

Edit: если вы не можете использовать strftime, вы хотите построить отформатированную дату в собственном буфере, вероятно, с помощью sprintf:

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

sprintf(buffer, "%s %d %d", months[monthnum], day, year); 
+0

его проект, и нам поручено обработать преобразование самостоятельно ... так что не использовать 'strftime' – SnakeDoc

+1

@SnakeDoc Но вы поняли, в чем смысл первого абзаца Джерри? В C нет никакой магии, как в других языках программирования; если вы собираетесь копировать байты с помощью 'strcat', вам нужно освободить место для них, и нет места после строковой константы. –

+0

@JimBalter Я опубликовал редактирование, показывающее мой модифицированный код, однако у меня все еще возникает ошибка сегментации. Похоже, что у меня может быть что-то не так с моей 'formatted = getMonth (месяц);' строка, так как если я добавлю printf и покажу «месяц», он будет корректным, но если я добавлю printf после указанной выше строки и отображу форматированный , я получаю ошибку сегментации. – SnakeDoc

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

После этого, вы можете продолжать изменять содержимое в массив символов «отформатированных».

+0

Эксплуатируемый код. –

+0

Да, этот фрагмент кода просто демонстрирует эту идею. Он не выполнял никаких проверок ошибок или проверки безопасности. – Sheng

+1

Правильно, но новички берут эти ответы, развивают плохие привычки, становятся профессиональными программистами, пишут кучи кода, и мы видели результаты. –

1

Вы не указали какую-либо память для форматирования. Измените объявление о отформатированных в

char formatted[80];

и изменить первое задание в отформатирован

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

, и вы должны быть в порядке.

1

Предположим, что ваш пост является правильным, то проблемы

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

возвращение strtok символ *, так что просто удалить & от каждого 'dateToken. И ваш прототип ввода 'getMonth' - это тип 'int', но вы указываете функцию 'char *' type, Таблица 'switch' не будет распознавать случай без цифр.

1

C не является языком для обработки строк. Если возможно, используйте C++ и std :: string.

Один из способов сделать это на C - это определить большой буфер char buffer[BUFFERSIZE], чтобы скопировать две строки в целях их конкатенации. Будьте осторожны, чтобы вы не переполняли буфер!

Вы также можете malloc/освободить буфер, но это еще один набор головных болей.

1

Вы можете решить некоторые ваши проблемы и упростить код с:

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

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

Таким образом,

  • возвращаемого значение записываемого
  • имеет дополнительное пространство для strcat() ОПС

Для промышленной прочности вы можете проверить возвращаемое значение malloc(), см., Если n находится в зоне действия, и тому подобное.

Смежные вопросы