main.cpp
#include <iostream>
#include "Module2.h"
int main()
{
std::cout<<"This is a test of Module2.h"<<std::endl;
std::cout<<UCase("This is a test of UCase")<<std::endl;
std::cout<<LCase("This is a test of LCase")<<std::endl;
system("pause");
return 0;
}
Module2.h
#include <iostream>
#include "Module2.h"
int main()
{
std::cout<<"This is a test of Module2.h"<<std::endl;
std::cout<<UCase("This is a test of UCase")<<std::endl;
std::cout<<LCase("This is a test of LCase")<<std::endl;
system("pause");
return 0;
}
Module2.cpp
///////////////////////////////////////////////////
//Module : Module2.cpp
//
//Purpose : Shows the usage of modular functions
///////////////////////////////////////////////////
#include "Module2.h"
///////////////////////////////////////////////////
//UCase()
char *UCase(char *str)
{
//convert each char in the string to uppercase
//
int len = strlen(str);
for ( int i ; i < len ; i++)
{
std::cout<<"In UCase"<<std::endl;
str[i]=toupper(str[i]);
}
return str;
}
///////////////////////////////////////////////////
//LCase()
char *LCase(char *str)
{
//convert each char in the string to uppercase
//
int len = strlen(str);
for ( int i ; i < len ; i++)
{
std::cout<<"In LCase"<<std::endl;
str[i]=tolower(str[i]);
}
return str;
}
Когда я запускаю его, нет ни предупреждения, ни ошибки.
Но это не верхняя и нижняя строка.
Я думал, что мои циклы for неправильны, но это кажется правильным.
Что не так с моим кодом?
Основная проблема заключается в том, что вы пытаетесь изменить строковые литералы, такие как "This is a test of UCase"
, Это неопределенное поведение. Вам нужно скопировать литералы в char
массив, который вы можете изменить.
Также обратите внимание, что обязательный char*
к строковому литералу не рекомендуется и запрещается по уважительной причине. Это должно было выдать предупреждение:
UCase("This is a test of UCase") // not good: binding char* to literal
Есть другие проблемы с вашим кодом: неопределенное поведение (UB) в циклах с неинициализированными переменными,
for ( int i ; i < len ; i++) // using uninitialized i: UB
Вы также должны взглянуть на toupper
а также tolower
документация. Они оба принимают int
с некоторыми ограничениями на их значения. Вы должны убедиться, что вы не передаете значение, которое вызывает неопределенное поведение, учитывая, что char
может быть подписано. Смотри например Нужно ли приводить к неподписанному символу перед вызовом? toupper
?
Такие циклы имеют неопределенное поведение:
for ( int i ; i < len ; i++)
Причина в том, что вы не начали i
по стоимости 0
,
Вы не представляете, в чем ценность i
начинается в!
Возможно -10
, может быть 824
,
Если вы хотите, чтобы значение было инициализировано, вы должен инициализировать это.
Я предлагаю:
for (int i=0; i < len; i++)
char *UCase( char *str)
{
char ch;
int i=0;
while(str[i])
{
ch=str[i];
putchar(toupper(ch));
//putchar : The value is internally converted to an unsigned char when written.
i++;
}
}
///////////////////////////////////////////////////
//LCase()
char *LCase(char *str)
{
char ch;
int i=0;
while(str[i])
{
ch=str[i];
putchar(tolower(ch));
i++;
}
}
Я наконец пишу это.
Хотя, я до сих пор не совсем понимаю, но я узнал
#include <ctype.h>
int tolower( int ch );
означает, что Tower Toupper может изменить только один символ каждый раз, поэтому я не могу
tolower ("This is a test of LCase");
код, как это.