2014-11-06 4 views
3

У меня есть-структура:Как преобразовать строку (символ *) в верхний или нижний регистр в C

typedef struct entry { 
char *surname; 
int house_no; 
char *postcode; 
} BEntry; 

и функция для преобразования строки в верхний регистр:

void toUpper(char *str){ 
    while (*str != '\0') 
    { 
     *str = toupper(*str); 
     str++; 
    } 
} 

и в моя главная функция Поручает значение членов структуры и хочет преобразовать фамилию заглавных букв:

mentry->surname = "bob"; 
mentry->house_no = 17; 
mentry->postcode = "GK116BY"; 
toUpper(me->surname); 

Что такое правильный способ CONVER t строка в верхний регистр, передавая указатель символа на такую ​​функцию? Моя программа возвращает ошибку сегментации. Любая помощь очень ценится, спасибо.

+0

Что не так с тем, что у вас есть ? –

+7

'' bob "' является строковым литералом, присутствующим в местоположении только для чтения. Вы не можете его изменить. Скопируйте и затем измените его. – Mahesh

+0

Проблема заключается в присвоении '' bob' - постоянной строки - к 'surname', которая имеет тип' char * '. У вас должно быть хотя бы предупреждение, что вы игнорируете const'ness в задании Всегда используйте полные предупреждения. Один из способов его решения - запустить 'char * strdup (const char s)' как часть назначения. Затем вы получите 'char *', который вы можете изменить. Не забудьте освободить память когда вы закончите. –

ответ

3

Ваш toUpper() реализация должна работать нормально. Однако вы должны обратить внимание на предупреждения своего компилятора (или включить уровни предупреждений, если вы их не получили), вы должны увидеть что-то, когда вы назначаете строковый литерал для char *, как это). Строковые литералы: const, т. Е. Они не могут быть изменены. Когда вы попытаетесь написать им, это приведет к видам сегментации, которые вы видите.

Вам нужно что-то вроде:

mentry->surname = malloc(4); 
strcpy(mentry->surname, "bob"); 

или более удобным, но не является частью стандартного пути C:

mentry->surname = strdup("bob"); 

И конечно, не забудьте вызвать free() позже, так или иначе ,

+0

Строковые литералы не являются 'const' в C. Я думаю, что это неправильно для стандартного определения этого способа, но, к сожалению, это так. Таким образом, OP не получит предупреждения. В gcc вы можете принудительно предупреждать в этом случае с '-Wwrite-strings', в этом случае программа нарушает стандарт, но это лучше, чем лучше. –

+0

@tristopia: Я думал, что они были, но я взглянул, и вы абсолютно правы. скажем, их изменение - это неопределенное поведение, которое вызывает вопрос, почему они не ... но да, поэтому нет очевидного исходя из этого. – FatalError

1

Строковые литералы, такие как "Hello, World!", не могут быть записаны. Либо дублировать строку буквальную:

hw = strdup("Hello, World!"); 

или объявить char[] переменные и инициализировать его в строку литерала. Как частный случай, строковые литералы, используемые таким образом, являются записываемые:

char hw[] = "Hello, World!"; 
+1

Литералы не могут быть записаны, также во втором случае вы показываете, что это не буквальный, который будет доступен для записи, а содержимое 'hw'. – alk

+0

@alk Это потому, что это не буквальный; Я знаю.Я написал ответ немного неверно, потому что его сложнее сформулировать и понять легче, чем правильную версию. – fuz

+1

В обоих случаях «Hello, World!» '** ** является буквальным. В обоих случаях это не ** записывается. – alk

0

Самый простой способ преобразования char * в нижний регистр или верхний регистр в С, с помощью strdup

#include <string.h> 

char *to_uppercase(char *s) 
{ 
    int i = 0; 
    char *str = strdup(s); 

    while (str[i]) 
    { 
     if (str[i] >= 97 && str[i] <= 122) 
      str[i] -= 32; 
     i++; 
    } 
    return (str); 
}