2015-09-25 61 views
0

所以我希望通过将char的值简单添加32来将大写字符转换为小写字母,这实际上是小写字母的等价形式。尝试为指向字符的指针数组赋值时发生C++崩溃

在主我声明指针数组,并分配3个字:

int main() 
{ 
    char *dictionary[10]; 
    dictionary[0] = "aUto"; 
    dictionary[1] = "caR"; 
    dictionary[2] = "Door"; 
    int arrayCount = 3; 
    upperCase(dictionary, &arrayCount); 
} 
在功能

我尝试转换:

void upperCase(char *dictionary[], int *arrayCount) 
{ 
    cout << "In upperCase\n"; 
    for (int i = 0; i < 3; i++) 
     for (int k = 0; dictionary[i][k] != '\0'; k++) 
     { 
      if (dictionary[i][k] < 97 && dictionary[i][k] > 64) // If  capital is less than the value of 'a' (97) 
      { 
       dictionary[i][k] += 32; 
      } 
      else 
       cout << "Not a capital\n"; 
     } 
} 

在字典中的程序崩溃[I] [k]的+ = 32; 我正在尝试替换字符串中的字符(它是由数组元素指向的)。即使先转换字母也不起作用。例如:字典[i] [k] ='a'; 仍然崩溃我的程序。 在windows上运行Eclipse C++

+1

你有一个指向字符串文字的指针数组。尝试修改字符串文字会导致未定义的行为。作为一个侧面说明,编译器已经为此作业提供了'std :: tolower'。 –

+0

标签'dynamic-arrays'不合适。 – WhiteViking

+0

如果你只是想用'char *'来混淆一下,那就完全没问题。但是对于几乎所有在C++中正常的字符串处理,您都需要使用'std :: string'。 – WhiteViking

回答

1

大部分情况可能在现在的评论中已经介绍过了。刚看了一下。对。我可以发帖前忙着。无论如何,这是一个问题的分解:

char *dictionary[10]; 

这很酷。

dictionary[0] = "aUto"; 

这并不酷。 “aUto”是string literal。一串常量值。如何存储取决于编译器。你可以阅读它,但你不应该指望能够写它。治疗好像被定义为const char *,因为就语言而言,它是const char *

为什么这不酷是OP分配const char *char *。将一个指向常量的指针指向非常量指针应该至少生成一个警告。最好在编译器中调出警告级别以尽早发现此类错误。在g ++和类似中,我喜欢-Wall,-Wextra,以及-pedantic的订单。在MSVC中,导航属性 - > C/C++ - >常规并使用警告级别进行播放。 EnableAllWarnings看起来是一个开始的好地方。

现在常量值被一个非常量指针引用,编译器不知道下一位可能是致命的。

dictionary[i][k] += 32; 

尝试将32添加到字符中,该部分正常,然后将结果存储到不可写位置。这是不允许的,但尝试不可能的确切处理取决于编译器。你有一个程序崩溃,这是非常好的编译器。程序可能一直在运行,砸了一些其他的内存空间,并在以后死亡,让你不知道究竟发生了什么以及要调试什么。

如何让这些字符串不是常数:

  1. 使用std::string而不是char *。在C++中,这是更好的选择。而当你在它的时候,使用std::vector而不是数组。
  2. 但是,这闻起来像功课,你可能不被允许使用std :: string。在这种情况下,分配存储并将字符串文字复制到存储中,以便它们具有支持它们的真实可修改内存。

编码风格注释:

而不是使用像97的数值,使用字符 'A'。它的工作原理相同,您的意图更容易确定。更好地节省自己的所有麻烦并使用std::tolower

你也可以用std::transform,std :: string和std :: tolower去除大部分的upperCase函数。试验一下,你会发现它。 更正(我总是觉得自己在这一点上):使用tolower,而不是std :: tolower,因为std :: tolower的语言环境重载使得它不明确你想要的std :: tolower。

此:

for (int i = 0; i < 3; i++) 

是种愚蠢。你传入了arrayCount。您不妨使用它,并保存自己从混乱,如果你改变数组中的项目数

for (int i = 0; i < *arrayCount; i++) 
+0

你真的把它打破了,非常感谢你。是的,它是家庭作业,我们不能使用字符串函数。这是试图帮助理解基础知识。 – Marc

-1

如果你允许使用C++,那么你可以改为:

  1. 使用STL
  2. 使用的载体,通常更容易来处理这类事情
  3. 使用字符串流(或一般流)

这只是一个想法。但是你的代码看起来更像C问题(它宁愿使用malloc来分配动态内存),而不是C++问题。

另外,你确定dictionary[i][k] += 32的操作真的在做你认为应该做的事吗?通常在这些类型的代码中崩溃意味着你的指针指向一个未分配/无效的地方。