为什么会出现分段错误

Why do I get an Segmentation fault error

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

#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;
}

You are given a sorted list of numbers with duplicates. Print out the sorted list with duplicates removed.

这是输入

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

既然你要我们猜,那我们就从头开始吧....

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

你的"online editor"传参了吗?我建议检查 argc > 1.


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

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

因此您将空指针传递给 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;
}

EDIT:另一种检查有效参数和 w/o strtokatoi:

的解决方案
#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;
}