在字符串 c++(无子字符串)上使用 str.find() 时执行操作

Perform operation when using str.find() on string c++ (no sub string)

本文关键字:字符串 find str 执行 操作 c++      更新时间:2023-10-16

我在检查.csv文件中的逗号时遇到问题。对于每一行,我想在找到第 10 个逗号时执行一个操作并检查该逗号之后的值。此值始终是小于 9 的数字。

int main()
{
    string row;
    ifstream infile;
    infil.open ("file.csv");
    int sum = 0;
    while(getline(infil,row))
    {
        for(int i = 0; i < row.size() ;i++)
        {
            if(row.find(',') != std::string::npos)
            {
                sum++;
            }
            if(sum == 10)
            {
                //PERFORM OPERATION
            }
        }
    }
return 0;
}

我写的代码不起作用,有什么帮助吗?

你可以使用这样的东西:

#include <iostream>
#include <fstream>
#include <string>
using std::string;
using std::ifstream;
using std::cout;
using std::cerr;
using std::endl;
int main()
{
    ifstream infile;
    //infile.open("file.csv");
    infile.open("C:\Users\Kraemer\Desktop\test.csv");
    string row;
    while (getline(infile, row))
    {
        int sum = 0; //number of commas
        size_t pos = 0; //Position in row
        //As long as we didn't find 10 commas AND there is another comma in this line
        while(sum < 10 && (pos = row.find(',', pos)) != string::npos)
        {
            //Comma found
            sum++;
            //Set position behind the comma
            pos++;
        }
        //When we come here sum is always <= 10
        if(sum == 10)
        {   //10 commas found 
            cerr << "Found 10 commas" << endl;
        }
        else
        {
            cerr << "Did not find enough commas in line" << endl;
        }
    }
    return 0;
}

您还应该注意到,当EOF位于包含数据的最后一行时,getline(infile, row)也会失败。因此,您需要在返回true时检查infile.eof()最后一个读取行,或者确保输入数据以空行结尾。

要提取第十个逗号后的数字,您可以执行以下操作:

if (sum == 10)
{   //10 commas found 
    cerr << "Found 10 commas" << endl;
    if (pos < row.size())
    {
        char digitAsChar = row[pos];
        if (digitAsChar >= '0' && digitAsChar <= '9') // Valid digit
        {
            int digitAsInt = digitAsChar - '0'; //Convert from char to int
            cout << "Found digit " << digitAsInt << endl;
        }
        else
        {
            cerr << "Character '" << digitAsChar << "' is no digit." << endl;
        }
    }
    else
    {
        cerr << "10th comma is at the end of the line - no digit found" << endl;
    }
}
else
{
    cerr << "Did not find enough commas in line" << endl;
}

输入:

,,,,,,,,,,1
,,,,,,,,,,2
,,,,,,,,,,3
,,,,,,,,,,4
,,,,,,,,,,5
,,,,,,,,,,f
,,,,,,,,,,
,,,,,,,,,,8
,,,,,,,,,9
,,,,,,,10

输出:

Found 10 commas
Found digit 1
Found 10 commas
Found digit 2
Found 10 commas
Found digit 3
Found 10 commas
Found digit 4
Found 10 commas
Found digit 5
Found 10 commas
Character 'f' is no digit.
Found 10 commas
10th comma is at the end of the line - no digit found
Found 10 commas
Found digit 8
Did not find enough commas in line
Did not find enough commas in line

尝试类似的东西

int main()
{
    string row;
    ifstream infile;
    infile.open ("file.csv");
    int sum = 0;
    while(getline(infile,row))
    {
        // sum = 0;  // you can reset sum at start of loop if you want,
                     //  or continue to use sum from last iteration
        int pos = row.find(','); // find first comma
        while (pos != std::string::npos)
        {
            if (++sum == 10)
            {
                //PERFORM OPERATION
                sum = 0; // reset comma count if you want
            }
            pos = row.find(',', ++pos); // find next comma (after pos)
        }
    }
    return 0;
}

这是一个最小的实现(不包括从文件中读取):

#include <iostream>
#include <string>
int main() {
  const std::string      row    = "a,b,c,d,e,f,g,h,i,j,7,k,l";
  size_t                 commas = 0;
  std::string::size_type pos    = 0;
  while (++commas <= 10) {
    pos = row.find(',', pos);
    if (pos == std::string::npos) {
      // Out of commas
      break;
    } else {
      ++pos;
    }
  }
  if (pos != std::string::npos) {
    int number = std::stoi(row.substr(pos, 1) );
    std::clog << "number = " << number << std::endl;
  }
}

输出:

number = 7

诀窍是跟踪最后找到的逗号的位置(在任何逗号找到之前以 0 开头)并将其用于第二个参数以std::string::find()

要扩展到"真正的"实现,应该将std::stoi()调用包装在try中,如果第十个逗号之后的任何内容不是数字(或太大),则catch执行任何需要做的事情。并且可能在最后一个块之后放一个else,并在row中没有十个逗号(或第十个逗号是最后一个字符)时执行任何需要做的事情。

不使用 string::find 的简单解决方案可能是这样的:

int main() {
    string s = "1,2,3,4,5,6,7,8,9,10,11";
    int n = 0;
    int i = 0;
    for(auto c : s)
    {
        if (c == ',')
        {
            ++n;
            if (n == 10) break;
        }
        ++i;
    }
    if (n == 10)
    {
        string tmp = s.substr(i+1);
        cout << "Rest of string is: " << tmp << endl; 
    }
    else
    {
        cout << "Only found " << n << endl; 
    }
    return 0;
}