【问题标题】:Printf and cout only printing first character of args cppPrintf 和 cout 只打印 args cpp 的第一个字符
【发布时间】:2013-08-12 06:57:03
【问题描述】:

我可能完全忽略了这一点,但我有以下方法可以在 Visual Studio 的 cpp 程序中打印出 args:

int _tmain(int argc, char* argv[])
{

    char* fu = "Bar";

    std::cout << "Test, " << argc << ", " << argv[0] << ", " << argv[1] << ", " << fu << endl;
        printf("%s, %s, %s", argv[0], argv[1], fu);
    return 0;
}

我遇到的问题是它似乎只打印 args 的第一个字符而不是整个字符串。

据我所知,argv[0] 取消引用 argv 数组以获取 char*,这就是我传递给 cout/printf 函数的内容。然后他们应该打印所有字符,直到 \0 字符。

我创建了测试 char* fu 以查看问题是否在于将 char* 传递给函数,但 'Bar' 已成功打印。

我唯一能想到的是因为 fu 的大小在编译时是已知的,而 argv 的大小并不是什么有趣的事情,因为它的编译方式正在发生。

我知道我可以通过遍历字符来打印出内容,但这似乎违背了这一点,例如,如果我想使用字符串进行比较或其他什么。有人可以解释一下发生了什么吗?

【问题讨论】:

  • 你提供了什么作为命令行参数?
  • 您确定 argv[] 不应该是 TCHAR 而不是 char,并且您可能正在使用 Unicode 版本的输入,这意味着您正在尝试打印 16 - 每个字符串的位为每个字符串 8 位 - 这几乎总是会导致这种特定类型的结果。
  • 命令行参数是:argv[0] 是可执行文件的路径/文件名(我认为这是正确的?),然后 argv[1] 是一串字符,例如“marrrrr”之类的.你是正确的 Mats,它是 TCHAR,我将其更改为 char 只是为了看看这是否与它有关,但它并没有帮助输出相同的东西..
  • 所以使用std::wcout 打印“宽”字符。
  • 10 分!微软传递 16 位值是多么烦人。然后我假设字节以小端方式(intel i5-3570k)传递,并且由于第二个字节全为0,它读取为字符串结尾?如果我使用的是大端处理器,那么它不会打印任何内容(就像幽灵一样!)?

标签: c++ visual-studio args


【解决方案1】:

_tmain 更改为main,或将char 更改为TCHARprintf 更改为_tprintf。您应该始终使用基于TCHAR 的设施,或者根本不使用。

很明显,您正在构建一个 Unicode 版本,并且传递给您的参数是 wchar_t* 指针,而不是 char*。通过将它们视为char*,您的程序会表现出未定义的行为。

【讨论】:

    【解决方案2】:

    问题是,您使用的可能是 Uni-Code 字符集。因此假定每个字符为 16 位(宽字符)。但是您解析的字符只有 8 位,因此您将较低的 8 位放入 16 位区域。你让其他 8 位免费。因此,在您的应用程序中,您将其视为非宽字符数组,并且您正在读取每个字节的字节,因此您获得了前 8 位,第二次您正在从未初始化的块中读取,这可能只是 0000 0000 (在你的情况下会设置一个 '\0' 标记)但它可以是任何东西,因为你还没有放入一些东西。

    解决此问题的最佳方法是(到目前为止,您不希望使用宽字符)只需进入您的 MSVC 项目属性,然后在 General->CharacterSet 下选择“使用多字节字符集”而不是“使用 unicode”。 然后你应该把 main 重命名为“main”,它应该在你的问题范围内工作。

    【讨论】:

    • 好吧,我忘了说,第二个字节是否初始化,取决于args的输入是视为char还是宽字符。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    相关资源
    最近更新 更多