Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从scanf读取C样式字符串时出现分段错误_C++ - Fatal编程技术网

C++ 从scanf读取C样式字符串时出现分段错误

C++ 从scanf读取C样式字符串时出现分段错误,c++,C++,我有以下简单的代码: #include <cstdio> #include <queue> #include <iostream> struct Pacient { int ill_state; int ev_num; bool operator==(const Pacient& other) const { return ill_state == other.ill_state && ev_num == other.ev_n

我有以下简单的代码:

#include <cstdio>
#include <queue>
#include <iostream>

struct Pacient {
int ill_state;
int ev_num;
bool operator==(const Pacient& other) const {
    return ill_state == other.ill_state && ev_num == other.ev_num;
}
bool operator<(const Pacient& other) const {
    return (ill_state < other.ill_state) || (ill_state == other.ill_state && ev_num > other.ev_num); // má menšiu prioritu, ak čaká kratšie (vyššie číslo na kartičke pri vstupe do ambulancie
}
bool operator>(const Pacient& other) const {
    return (ill_state > other.ill_state) || (ill_state == other.ill_state && ev_num < other.ev_num);
}
};

int main() {
char* ccmd;
std::priority_queue<Pacient> ps;
int ev_num, ill_state;
while (std::scanf("%s", ccmd)) {
    std::string cmd(ccmd);
    if (cmd == "dalsi") {
        if (ps.empty()) {
            std::printf("-1\n");
        } else {
            std::printf("%d\n", ps.top().ev_num);
            ps.pop();
        }
    } else if (cmd == "pacient") {
        std::scanf("%d%d\n", &ev_num, &ill_state);
        Pacient new_ps;
        new_ps.ev_num = ev_num;
        new_ps.ill_state = ill_state;
        ps.push(new_ps);
    } else if (cmd == "koniec") {
        break;
    }
}
return 0;
}
我使用的是Ubuntu 13.10 64位。 谁能解释一下,是什么引起了这个问题


注意:我使用的是scanf而不是cin,因为我(从学校)得到了使用scanf、printf而不是cin的具体指导。否则我不会使用它。

您没有初始化指针
ccmd

char* ccmd;
并且没有将内存分配给要读取字符串的位置

while (std::scanf("%s", &ccmd)) {
因此程序具有未定义的行为

完全不清楚为什么您不想在stream
std::cin
中使用operator>>,而是使用不安全的函数scanf

您还需要包含标题
。否则,如果您试图用其他编译器编译您的程序,您可能会收到一条错误消息

正如所指出的那样,即使函数scanf的调用也是不正确的。而不是

std::scanf("%s", &ccmd)
应该有

std::scanf("%s", ccmd)

您不需要使用
std::scanf
来读取字符串,您可以使用安全的C++:

std::string cmd;
while(std::cin >> cmd) {
    // ...
}

为要写入的
scanf
声明一些存储:

char ccmd[1000];
否则,
*ccmd
是一个随机指针,其(可能)存储空间不足,无法写入字符。请注意,
scanf
不会在该空间上执行间接寻址

另外,
ccmd
已经是一个指针,因此不需要额外的
&
(的地址):

 std::scanf("%s", ccmd)


scanf
在使用“%s”时需要一个
char*
。也就是说,使用
std::string
operator>
std::getline
@Aashish是的,我可以,但我有使用scanf和printf的具体说明。@chris我已经在使用它了。你的标题完全不正确:你没有使用
scanf
读取
std::string
,您正试图读取一个c样式的字符。@crashmstr谢谢,修复了这个问题。请您更具体一点好吗?例如,究竟如何初始化该指针?@Benji它必须引用分配的内存,您将在其中读取字符串。现在这个指针有一些任意值。您将
char**
传递到
%s
格式,这是不正确的。但是您可以执行
sscanf(“%ms”,&ccmd)
,它将在使用glibc时为您分配一个缓冲区。这是一个非标准的扩展。我有特殊的指令(从学校)使用SCANF和PrimTf在这个代码中。@ Beji这很奇怪,他们要求你使用C++和C风格的输入/输出。我听说这是因为输入这个程序将非常大,而且SCANF应该比CIN快。@ BunjyOH,毫秒浪费了!严重的是,他们应该教你正确的惯用C++代码,然后担心性能。@ Beji请注意,代码> SCANF函数族容易将堆栈溢出引入到应用程序中,如<>代码> SCANF(“%s”)确实如此,因为你没有指定要读取的最大字符串长度。换句话说,
scanf
函数族更难正确使用。为了防止堆栈溢出:
std::scanf(“%999s”,ccmd)
@MaximYegorushkin:updated to address(稍微优雅一些)。您确定
*
允许您指定最大字段宽度吗?另外,
%s
的字段宽度不应包括
\0
的空间,即ccmd-1的大小
@MaximYegorushkin:哦,你说得很对。收回。@wallyk我希望它能允许(。
 std::scanf("%s", ccmd)