【问题标题】:Defining char array based on choice in C++根据 C++ 中的选择定义 char 数组
【发布时间】:2013-10-05 08:26:07
【问题描述】:

我对 C++ 非常陌生,并且已经尝试自学了几天。 如果我的问题很明显或以前被问过,我提前道歉,我已经多次寻找解决方案,我似乎看到的所有解决方案都比我的直觉告诉我需要的更复杂,而且通常超出我的想象。 ..无论如何,对于我的问题的长篇介绍感到抱歉:

我只是试图根据来自多项选择问题的输入来确定 wchar_t 数组(它只是一个 unicode 字符串?)的值(或者我猜值......数组仍然有点可怕)。

这是我到目前为止所做的:

#include "stdafx.h"
#include <iostream>
#include <string>
#include "easendmailobj.tlh"
using namespace EASendMailObjLib;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    const int MAX = 65;
//char server[MAX], serverName[MAX], userName[MAX], password[MAX], from[MAX], to[MAX], msg[160];

//Choosing a SMTP server
int choice = 0;
bool logon = true;
bool ssl = true;
cout << "1)Gmail\n"
     << "2)Yahoo\n"
     << "3)Hotmail\n"
     << "4)None (Experemental)\n"
     << "5)Other (Advanced)\n"
     << "What kind of E-mail would you like to send from?:";
cin >> choice;

switch(choice) {
    case 1: wchar_t server[] = _T("smtp.gmail.com");
            char serverName[] = "Gmail";
            break;
    case 2: wchar_t server[] = _T("smtp.mail.yahoo.com");
            char serverName[] = "Yahoo";
            ssl = false;
            break;
    case 3: wchar_t server[] = _T("smtp.live.com");
            char serverName[] = "Hotmail";
            break;
    case 4: wchar_t server[] = _T("");
            logon = false;
            ssl = false;
            break;
    case 5: cout << "Enter your server:";
            char server[MAX];
            wcin.getline(server, MAX, '\n');
            cout << "Does your server require a login? (true or false):";
            cin >> logon;
            cout << "Does your server require an SSL connection? (true or false):";
            cin >> ssl;
            break;
    default: cout << endl <<"You entered a wrong number, restart, and try again."
                  << endl;
    }
}

这似乎一切都很好,但是当我尝试编译时,它会抛出关于多次声明同一个变量的各种错误,我有点明白,但每个人都应该根据选择运行一个错误,对吗?我会先声明所有内容,然后根据选择进行定义,但据我所知,这在 C++ 中是不可能的。

我真的被困在这里,非常感谢您的耐心和帮助。

【问题讨论】:

  • 启用编译器中的所有警告和调试信息。学习使用调试器。

标签: c++ arrays string input


【解决方案1】:

问题是case块都属于同一个范围。

即使你在声明之间有一个中断,编译器也不在乎。它所看到的只是多次声明的相同变量serverserverName。这也不是您想要的,因为在 switch 语句之后您将无法访问它们。

您需要做的是在 switch 语句之前声明它们并为其分配一些明显错误的值(例如"undefined")。

只需确保您的默认案例正确处理事情,并且您不会使用您分配的默认值继续执行。

【讨论】:

    【解决方案2】:

    我建议声明(在您的 main 函数中,或作为全局变量)

     std::string server;
     std::string servername;
    

    您不希望这些变量在 case-s 内的每个块中都是本地的。

    和编码类似的东西

     case 1: server = "smtp.gmail.com";
             servername = "gmail";
             break;
    

    您可能想检查一个字符串是否为空,例如if (servername.empty()) ...

    顺便说一句,您似乎没有使用标准 C++ 编写代码:函数名称 _tmain 不是标准开头的(使用 int main(int argc, char**argv))。

    【讨论】:

    • 该 _tmain() 调用是使用 MS Visual C++ 的模板代码,默认情况下会为控制台应用程序项目创建 Microsoft 特定的代码。一旦选择了该项目模板,该 _tmain() 入口点并首先包括“stdafx.h”是强制性的。 VC++ 可以创建标准的 C++ 项目,但没有内置模板。 (...而且 express 产品不支持用户定义的模板。) wchar_t 服务器名称使它看起来像是要使用特定于 MS 的 API,所以这很可能是合理的。
    • 首先,非常感谢你们的回复。 Mike 是正确的,因为我正在使用 VC++,并且在程序中还有一些借用的代码,特别是涉及发送电子邮件。到目前为止,我一直认为这与字符集有关,但 Mike 所说的对我来说似乎很有意义。如果有人能提供有关在这些数据类型之间获取的任何信息,那将非常有帮助。
    【解决方案3】:

    编译器不喜欢你在同一作用域(即开关作用域)中声明相同的变量serverserverName。请注意,如果您在每个 case 块周围添加 {};,则可以:

    case 1: {wchar_t server[] = _T("smtp.gmail.com");
            char serverName[] = "Gmail";
            break;};
    

    但是,这些变量在这些范围之外将不可用。对于您要执行的操作,您需要将变量放在 main 范围内,然后在 switch case 中更改它们。

    另外,我建议使用字符串,至于数组需要立即声明大小,或者在开关中使用指针和 malloc。

    【讨论】:

      【解决方案4】:

      您的 server 和 serverName 变量存在两个问题。首先,它们在 switch 块内部定义,在 switch 块外部不可见。其次,它们在该块中被多次定义。

      完成此操作的一种方法是在 switch 块之前将 serverName 定义为 char 指针,然后在每个 case 子句中使用赋值来设置。对 server[] 变量执行相同操作:

      const char *serverName="";
      const wchar_t *server = _T("");
      switch(choice) {
          case 1: server = _T("smtp.gmail.com");
                  serverName = "Gmail";
                  break;
          case 2: server = _T("smtp.mail.yahoo.com");
                  serverName = "Yahoo";
                  ssl = false;
                  break;
          ...etc.
      }
      

      【讨论】:

      • 我记得在我的学习中读过一些关于指针的东西,但我略读了一下,因为它对我来说似乎太高级了,但它看起来正是我所需要的。我会回去更详细地阅读它们,但现在你向我展示的示例足以解决我现在需要的问题并让我重新开始,非常感谢。
      • 我在尝试时注意到的一件事是“wcin.getline”不再有效,有人可以对上面的示例进行轻微扩展以包含该部分吗?
      • @Bendude137 您需要使用宽字符数组以及宽字符。结束行字符也必须加宽。
      猜你喜欢
      • 2021-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-25
      • 1970-01-01
      • 2022-11-13
      • 2021-08-03
      相关资源
      最近更新 更多