strcmp的分段错误

时间:2011-09-11 15:58:26

标签: c++

我正在尝试读取文件并将每行分成几部分,当我尝试执行strcmp或strncmp时,我会发生分段错误。有人可以帮我吗?

char *input_file = argv[1];
char *line;
char *type = NULL;
ifstream infile;
infile.open(input_file, ifstream::in);
while(!infile.eof())
{
    std::string s;
    std::getline(infile, s);
    line = new char[s.length()+1];
    strcpy(line, s.c_str());
    type = strtok(line,"(");
    cout<<"type"<<type<<"\n";
    if(s.size()>0)
        s.resize(s.size()-1);
    if(s[0]=='#')
        continue;
    if(!strncmp(type,"INPUT",5))

3 个答案:

答案 0 :(得分:5)

使用字符串(和流)可能会更容易,当然更多的是“C ++”:

std::string line;

while (std::getline(infile, line))
{
  // process "line", e.g. by tokenizing:
  std::istringstream iss(line);
  std::string token;
  while (iss >> token)
  {
    // process token, e.g. use token.substr(...)
  }

  // or directly, as a whole:
  std::cout << line.substr(line.find_first_of('(') + 1) << std::endl;
}

答案 1 :(得分:3)

一些问题:

  1. 您没有检查strtok的返回值是否为NULL。将此值传递给strncmp时,这可能会导致分段错误。
  2. s[0]可能是空字符串时,您正在访问s
  3. 正如Tomalak Geret'kal在上面的评论中所说,不要使用while(!infile.eof())。请改用while(std::getline(infile, s))。即使eof()返回false,从流中读取也可能失败。

答案 2 :(得分:3)

我认为没有任何理由在这里使用C风格的字符串函数。试图坚持大致相同的名称以保持意图明显,我会做这样的事情:

std::string s, type;

while (std::getline(infile,s)) {
    int paren = s.find('(');
    if (paren != std::string::npos)
        type = std::string(s, 0, paren);
    std::cout << "type" << type << "\n";
    if (s[0] == '#')
        continue;
    if (std::string(s, 0, 5) == "INPUT")
         // presumably more here...

根据您真正想要实现的目标,很有可能进一步改善这一点。我的直接反应是做类似的事情:

// There's probably a better name for this, but I don't know what.
struct line {
    std::string type;
    std::string tail;

    friend std::istream &operator>>(std::istream &is, line &l) { 
        std::getline(is, l.type, '(');
        std::getline(is, l.tail);
        if (l.tail.size() > 0)    // There's probably room for improvement here.
            l.tail.resize(l.tail.size()-1);
        return is;
    }
};

然后您可以使用以下内容:

line x;

while (infile >> x) {
    std::cout << "type" << x.type << "\n";
    if (std::string(x.type, 0, 5) == "INPUT")
        // whatever

如果您总是将输入的前五个字符(或某些分隔符等)视为某种命令(或其他),您可以让line类解析出来也分开。