【问题标题】:Reading from file and avoiding white space in blank lines从文件中读取并避免空白行中的空格
【发布时间】:2012-09-09 10:53:49
【问题描述】:

我目前正在从事一个项目,我正在阅读命令,我需要避免空白行出现空格。到目前为止,我做得很好,但由于某种原因,我似乎无法弄清楚如何让它发挥作用。我以为if(opcode == "\t" || opcode == " ")continue; 会照顾好,但事实并非如此。如果有人可以请看一下并帮助我,那就太好了。

这是我正在阅读的命令的一个小示例。它们采用 [label] opcode [arg1][,arg2] 格式。

#Sample Input
LA 1,1
LA 2,2
\t <<<<<<<Here just to show that it's a blank line with only a tab
TOP NOP

这是我的代码:

    int counter = 0;
int i = 0;
int j = 0;
int p = 0;

while (getline(myFile, line, '\n'))
{


    if (line.length() == 0)
    {
        continue;
    }

    if (line[0] == '#')
    {
        continue;
    }


    // If the first letter isn't a tab or space then it's a label

    if (line[0] != '\t' && line[0] != ' ')
    {

        string delimeters = "\t ";

        int current;
        int next = -1;


        current = next + 1;
        next = line.find_first_of( delimeters, current);
        label = line.substr( current, next - current );

        Symtablelab[i] = label;
        Symtablepos[i] = counter;

        if(next>0)
        {
            current = next + 1;
            next = line.find_first_of(delimeters, current);
            opcode = line.substr(current, next - current);


            if (opcode != "WORDS" && opcode != "INT")
            {
                counter += 3;
            }

            if (opcode == "INT")
            {
                counter++;
            }

            if (next > 0)
            {
                delimeters = ", \n\t";
                current = next + 1;
                next = line.find_first_of(delimeters, current);
                arg1 = line.substr(current, next-current);

                if (opcode == "WORDS")
                {
                    counter += atoi(arg1.c_str());
                }
            }

            if (next > 0)
            {
                delimeters ="\n";
                current = next +1;
                next = line.find_first_of(delimeters,current);
                arg2 = line.substr(current, next-current);

            }
        }

        i++;

    }

    // If the first character is a tab or space then there is no label and we just need to get a counter
    if (line[0] == '\t' || line[0] == ' ')
    {
        string delimeters = "\t \n";
        int current;
        int next = -1;
        current = next + 1;
        next = line.find_first_of( delimeters, current);
        label = line.substr( current, next - current );

    if(next>=0)
        {
            current = next + 1;
            next = line.find_first_of(delimeters, current);
            opcode = line.substr(current, next - current);



            if (opcode != "WORDS" && opcode != "INT")
            {
                counter += 3;
            }

            if (opcode == "INT")
            {
                counter++;
            }


            if (next > 0)
            {
                delimeters = ", \n\t";
                current = next + 1;
                next = line.find_first_of(delimeters, current);
                arg1 = line.substr(current, next-current);

                if (opcode == "WORDS")
                {
                    counter += atoi(arg1.c_str());
                }

            }



            if (next > 0)
            {
                delimeters ="\n\t ";
                current = next +1;
                next = line.find_first_of(delimeters,current);
                arg2 = line.substr(current, next-current);

            }
        }

    }
}

【问题讨论】:

    标签: c++ whitespace removing-whitespace


    【解决方案1】:

    使用 std::stringstream 并从您的行中读取 std::string 变量。这样空格就被省略了。

    [更新] 如果你想从头开始删除空白:

    s.erase(s.find_last_not_of(" \n\r\t")+1);

    [UPDATE2] 或者只是在阅读时数单词:

    就像这个例子:

    #include <iostream>
    #include <sstream>
    #include <string>
    
    int main() {
    
      std::string line;
      while (std::getline(std::cin, line))
      {
          std::string lineNoWS = line;
          lineNoWS.erase(lineNoWS .find_last_not_of(" \n\r\t")+1);
          if (lineNoWS.empty())
            std::cout << "EMPTY LINE\n";
    
          std::string word;
          unsigned words = 0;
          std::istringstream line_is(line);
          while(line_is >> word)
          {
             std::cout << '\'' << word << "'\n"; 
             ++words;
          }
          std::cout << "(" << words << ")ENDLINE\n"; 
      }
    }
    

    只需将 std::cin 替换为您的 ifstream(file)

    【讨论】:

    • 你介意用空白行解释一下如何做到这一点。我以前使用过 stringstream,但从来没有像这样删除空格。
    • 查看我的更新。我添加了对仅包含空格的跳行的支持。
    • 我想我只是不确定如何在不改变整个程序的情况下实现这一点。
    • 我不明白你的整个程序。你能用line.erase(line.find_last_not_of(" \n\r\t")+1);从一开始就吃掉所有的空白吗?这对您的程序从头开始跳过所有空格并检查其余部分是否有效?
    【解决方案2】:

    您可能应该尝试使命令的阅读更加“通用”。 假设一行有效必须以标签开头,并且您的标签只能包含“字母”,而不是检查 '\t'、'\n'、'\r'、'#'、(...) 为什么不直接使用 isalpha 函数?

    然后你需要获取参数,假设它们用''分隔,你最好的方法是根据','分隔符分割行。

    一些示例代码,为您提供“标签”和带有“参数”的向量,我建议您也验证标签(例如检查标签是否仅由字母组成,并假设您知道“命令”验证您为特定标签检索的参数的数量和类型。

    std::ifstream inStream("c:\\data\\dump.txt");   
        if(!inStream.fail())
        {
            while(!inStream.eof())          
            {
                std::string strLine;
                std::getline(inStream, strLine);
    
                // Label ?
                if( isalpha(strLine[0]))
                {
                    int iIndexOf = strLine.find(" ");
                    if(iIndexOf != string::npos)
                    {
                        std::string strLabel = strLine.substr(0, iIndexOf);
    
                        // Arguments ?
                        std::vector<std::string> vArguments;
                        std::stringstream ss(strLine.substr(iIndexOf, strLine.size() - iIndexOf));  
    
                        std::string strArgument;
                        while(std::getline(ss, strArgument, ','))   
                        {                           
                            if(strArgument.size()!=0)                                                           
                                vArguments.push_back(strArgument);
                        }
    
    
                        std::cout << "label: " << strLabel << std::endl << "arguments list: ";
                        for(size_t i=0; i<vArguments.size(); i++)
                            std::cout << vArguments[i] << ";";
                        std::cout << std::endl;
                    }
                    else
                    {
                        // No Arguments
                        std::string strLabel = strLine;                                     
                        std::cout << "label: " << strLabel << std::endl;                    
                    }
                }           
            }
    
            inStream.close();
        }
    

    【讨论】:

      猜你喜欢
      • 2019-04-08
      • 1970-01-01
      • 2020-03-30
      • 1970-01-01
      • 1970-01-01
      • 2018-10-18
      • 1970-01-01
      • 2015-01-30
      • 1970-01-01
      相关资源
      最近更新 更多