涉及字符串输入和字符串比较的scanf问题

时间:2016-02-06 06:11:00

标签: c++ c c++11

我刚刚开始研究scanf和printf,在我的研究和一般情况下,我已经多次遇到我的代码中的问题所以我决定制作一个测试程序并成功复制错误。

#include <string>
#include <string.h>
#include <stdio.h>

int main(){
    std::string name;
    std::string name2;

    printf("Print donald or larry: ");
    scanf("%s",name);

if(strcmp(name.c_str(), "donald") == 1){
    printf("You entered donald");
    goto stop;


}else{
    printf("You entered larry");
    goto stop;
}



stop:
return 0;
}

当我尝试编译代码时,它会抛出来自第10行的错误

错误:

error: cannot pass objects of non-trivially-copyable type 'std::string {aka
class std::basic_string<char>}' through '...'|

源:

scanf("%s", name);

我已经尝试了name.c_str&name,但它们都不起作用,name.c_str使if语句出错并且不起作用,但&name只是完全崩溃,虽然我发现&<variable>目前只适用于整数。

我做错了什么?

3 个答案:

答案 0 :(得分:6)

如果您正在尝试编写C ++代码,请使用以下

#include <iostream>
using std::cout;
using std::endl;
using std::cin;
#include <string>
using std::string;

int main(){

    // declare the string object
    std::string name;

    // output prompt and get input
    cout << "Print donald or larry: ";
    cin >> name;

    if (name == "donald") {
        cout << "You entered donald" << endl;
    }
    else if (name == "larry") {
        cout << "You entered larry" << endl;
    }

    return 0;
}

你正在做一些事情&#34;错误&#34;在上面的代码中。

  1. scanf和printf是C函数,应该与cstrings一起使用而不是string个对象。如果您使用的是std::string,那么您使用C ++进行编程,并且应该使用C ++标准库头<iostream>提供的功能
  2. 在代码中使用goto通常是一个坏主意。

答案 1 :(得分:2)

  

我做错了什么?

主要问题是你在这种情况下混合 apples oranges (或C和C ++)。虽然可以混合C / C ++ I / O,但出于多种原因不推荐使用它。您的声明std::string name;尝试声明与基本char *类型不同的C ++字符串对象。因此,当您尝试使用基本C scanf填充C ++字符串对象时,您会收到错误。为什么?因为scanf需要简单的char *指针用于名称,并且您提供的是C ++ 字符串对象。因此,最好坚持使用 apples oranges ,而不是尝试将C ++对象与标准C函数混合使用。

如果您正在尝试编写C代码来调查scanf系列函数,那么您将需要类似于以下内容的内容:

#include <stdio.h>
#include <string.h>

enum { MAXCHR = 64 };

int main (void) {

    char name[MAXCHR] = {0};  /* simple character array initialized to 0 */

    printf ("Print donald or larry: ");
    if (scanf ("%63[^\n]%*c",name) != 1) {  /* check the return of scanf */
        fprintf (stderr, "error: insufficient input.\n");
        return 1;
    }

    if (strcmp (name, "donald") == 0)       /* string comparisons */
        printf ("You entered donald\n");
    else if (strcmp (name, "larry") == 0)
        printf ("You entered larry\n");
    else
        printf ("You entered '%s' (neither 'donald' or 'larry')\n", name);

    return 0;
}

示例使用/输出

$ ./bin/scanf_name
Print donald or larry: donald
You entered donald

$ ./bin/scanf_name
Print donald or larry: larry
You entered larry

$ ./bin/scanf_name
Print donald or larry: moe
You entered 'moe' (neither 'donald' or 'larry')

如果您要使用scanf(或任何一系列功能),那么花时间仔细阅读和消化功能的手册页是非常值得的。 format-string 格式说明符有许多微妙的注意事项,如果您不完全理解它们,可能会咬你。 scanf函数系列有它们的位置,但在从用户那里获取输入时考虑使用面向行的输入函数(例如C中的fgetsgetline)不太容易出现微妙的I / O问题。

答案 2 :(得分:-5)

scanf不支持任何C ++类。如果你想阅读C ++ string,你可以做类似的事情:

std::string str(256, ' ');
if (1 == scanf("%*s", &str[0], str.size())) {
    // ...
}

但是,这并不能解释为什么您不想使用cin