【问题标题】:Why do I get an Segmentation fault error为什么我会收到分段错误错误
【发布时间】:2015-08-20 14:17:04
【问题描述】:

我的代码在我的计算机上的 codeblocks 编译器上运行良好,但是当我将它上传到在线编辑器时,我收到 Segmentation fault 错误,我不知道为什么。

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <fstream>
using namespace std;
int main(int argc, char *argv[]) {
    ifstream stream(argv[1]);
    char line[1000];
    int x,last=-1;
    while (stream>>line)
    {
        x = atoi(strtok(line,","));
        cout<<x;
        last=x;
        while(x=atoi(strtok(NULL,",")))
        {
            if(x!=last)
            {
                cout<<","<<x;
                last=x;
            }
        }
        cout<<endl;
    }
    return 0;
}

您会得到一个排序后的数字列表,其中包含重复的数字。打印出已删除重复项的排序列表。

这是输入

6,7,8,9,9,10,11,12,13,14,15
11,12,13,14,15,16,17,18,19,20
2,2,2,2,2
10,11,12,13,14,15,16,16,17
13,14,14,15,16,17,17,17,18
15,16,17,17,18,18,18,18,19,19,20
2,3,4,5,5
13,14,15,16,17
10,11,12,13,14,15,15,15,15,16,16,16
12,13,14,15,16,17,17,18
5,6,7,8,9,10,11
14,14,14,15,15,16,17,17,18,19,19,20,21,22
13,14,15,16,16,17,17,18
15,16,17,18,19,20,21,21,21,21,22,22
6,6,6,7,8,9,10,11,11,11,12,12,13
12,12,13,14,15,15,16,17,17,18,19,19,20,21
8,9,9,9,10,10,11,12,13,13,14,15
12,13,14,15,16,17,18
1,1,1,2,2,3,3,4,4
1,2,3,4

【问题讨论】:

  • 什么“在线编辑器”?你给我们留下的只是猜测。
  • 顺便说一句,如果该代码应该一次读取一行,那么您做错了。而且我不知道您为什么使用 C 数组进行字符串存储。或用于字符串操作的 C 函数。你也没有正确地做strtok(你在哪里检查最终令牌???)。事实上,我越看这个,它就越错误。
  • 我不知道这条线想要做什么:while(x=atoi(strtok(NULL,",")))。你为什么在NULL 上打电话给strtok?另外,赋值运算符是否应该是==?
  • @Carlton NULL 到 strtok 很好。 NULL 到 atoi 是可疑的。
  • @Carlton,是的,在 first 调用时不行,但 OP 没有这样做。

标签: c++ segmentation-fault


【解决方案1】:

既然你要我们猜,让我们从顶部开始......

代码不会检查argv[1] 是否有效。如果不是,那么您只是取消引用了一个空指针,这导致了您的分段错误。

您的“在线编辑器”是否传递参数?我建议检查argc &gt; 1。


接下来,您的代码看起来会在每一行的末尾传递一个指向atoi 的空指针。这是另一个分段错误。

【讨论】:

  • 使用 VS2012 快速测试和有效输入文件在 atoi 上崩溃。
【解决方案2】:

您正在调用atoi,结果为strtok。 如果strtok 没有找到任何东西,它会返回一个空指针。 这是行尾的情况。

所以你将一个空指针传递给atoi,这会导致崩溃。

使用您的示例应该可以: #define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <fstream>


using namespace std;
int main(int argc, char *argv[]) 
{
    ifstream stream(argv[1]);
    char line[1000];
    char* ln;
    char* num;
    int x;
    int last;

    while (stream >> line)
    {
        ln = line;
        last = -1;
        while (num = strtok(ln, ","))
        {
            x = atoi(num);
            if (x != last)
            {
                if(last != -1) cout << "," << x;
                else cout << x;
                last = x;
            }
            ln = NULL;
        }
        cout << endl;
    }
    return 0;
}

编辑:另一种解决方案,检查有效参数并且不带strtok 和atoi:

#define  _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <fstream>


using namespace std;
int main(int argc, char *argv[]) 
{
    if (argc < 2) {
        cout << "Usage: " << argv[0] << " <file>";
        return 1;
    }

    ifstream stream(argv[1]);
    if (!stream.is_open())
    {
        cout << "Failed to open file \"" << argv[1] << "\"";
        return 2;
    }

    char line[1000];
    while (stream >> line)
    {
        int last = -1;
        int x = 0;
        for (char* pos = line; pos < line + strlen(line); pos++)
        {
            if (*pos >= '0' && *pos <= '9')
            {
                x = (x * 10) + (*pos - '0');
            }
            else
            {
                if (last != x)
                {
                    if (last != -1) {
                        cout << ',';
                    }
                    cout << x;
                    last = x;
                }
                x = 0;
            }
        }
        cout << endl;
    }
    return 0;
}

【讨论】:

  • 谢谢,在代码块中 atoi on NULL 返回了 0 值,所以我不知道这会是个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多