Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何按升序对输入进行编号?_C++_String_C++11_Io - Fatal编程技术网

C++ 如何按升序对输入进行编号?

C++ 如何按升序对输入进行编号?,c++,string,c++11,io,C++,String,C++11,Io,我以文件input.txt的形式输入两列字符串,例如: string1 string2 string3 string4 etc. 我试图从0开始按升序对字符串进行编号,但这样重复的字符串不会被分配新的值,而是保留已分配给它们的值。 我决定使用set::find操作来完成这项工作,但我很难让它工作。以下是我目前掌握的情况: int main(int argc, char* argv[]) { std::ifstream myfile ("input.txt"); std::strin

我以文件input.txt的形式输入两列字符串,例如:

string1 string2
string3 string4
etc.
我试图从0开始按升序对字符串进行编号,但这样重复的字符串不会被分配新的值,而是保留已分配给它们的值。 我决定使用set::find操作来完成这项工作,但我很难让它工作。以下是我目前掌握的情况:

int main(int argc, char* argv[]) { 

  std::ifstream myfile ("input.txt");
  std::string line;
  int num = 0;  // num is the total number of input strings

  if (myfile.is_open()) {      
      while(std::getline(myfile, line)) {
          ++num; 
      }
  }

  std::string str1, str1; // strings form input
  int str1Num, str2Num; // numbers assigned to strings

  int i = 0; // used to assign values to strings
  StringInt si;
  std::vector<StringInt> saveStringInts(num);
  std::set<std::string> alreadyCounted(num, 0); 
  std::set<std::string>::iterator sit;

  std::ifstream myfile2 ("input.txt");
  if (myfile2.is_open()) {      
      while(myfile2.good()) {
          // read in input, put it in vars below
          myfile2 >> str1 >> str2;

    // if strings are not already assigned numbers, assign them
    if ((*(sit = alreadyCounted.find(str1)).compare(str1) != 0) { // doesn't work
      str1Num = i++;
      alreadyCounted.insert(str1);
      saveStringInts.push_back(StringInt(str1Num));
    }
    else {
      str1Num = si->getNum(str1);
    }
    if ((*(sit = alreadyCounted.find(str2)).compare(str2) != 0) { 
      str2Num = i++;
      alreadyCounted.insert(str2);
      saveStringInts.push_back(StringInt(str2Num));
    }
    else {
      str2Num = si->getNum(str2);
    }

    // use str1 and str2 in the functions below before the next iteration


    }
  }
intmain(intargc,char*argv[]){
std::ifstream myfile(“input.txt”);
std::字符串行;
int num=0;//num是输入字符串的总数
如果(myfile.is_open()){
while(std::getline(myfile,line)){
++num;
}
}
std::string str1,str1;//字符串表单输入
int str1Num,str2Num;//分配给字符串的数字
int i=0;//用于为字符串赋值
StringInt si;
std::向量saveStringInts(num);
std::设置已计数(num,0);
std::set::迭代器;
std::ifstream myfile2(“input.txt”);
如果(myfile2.is_open()){
while(myfile2.good()){
//读入输入,将其放入下面的变量中
myfile2>>str1>>str2;
//如果字符串尚未指定编号,请指定它们
如果(*(sit=alreadyCounted.find(str1)).compare(str1)!=0{//不起作用
str1Num=i++;
已计算。插入(str1);
saveStringInts.push_back(StringInt(str1Num));
}
否则{
str1Num=si->getNum(str1);
}
如果(*(sit=alreadyCounted.find(str2)).compare(str2)!=0{
str2Num=i++;
已计算。插入(str2);
saveStringInts.push_back(StringInt(str2Num));
}
否则{
str2Num=si->getNum(str2);
}
//在下一次迭代之前,在下面的函数中使用str1和str2
}
}

不幸的是,我尝试了其他方法,现在完全卡住了。如果您知道如何修复我的代码,或者可以建议一种更好的方法来完成我的任务,我将非常感谢您的帮助。

您需要将
std::set::iterator
end()进行比较
iterator,而不是取消对迭代器的引用并将其值与某些内容进行比较!实际上,取消对
end()迭代器的引用是未定义的行为:

if ((*(sit = alreadyCounted.find(str1)).compare(str1) != 0) // WRONG: don't do that!
应该是

if (alreadyCounted.find(str1) != alreadyCounted.end())
…另一个字符串也是如此。不过,我个人会使用另一种技术:当
insert()
插入
std::set
时,您会返回一对迭代器和一个指示器,指示是否插入了对象。后者与当前集的大小一起给出下一个值,例如:

bool result = alreadyCounted.insert(str1).second;
strNum1 = result? alreadyCounted.size() - 1: si->getNum(str1);

您需要将
std::set::iterator
与集合的
end()
迭代器进行比较,而不是取消对迭代器的引用并将其值与其他内容进行比较!实际上,取消对
end()
迭代器的引用是未定义的行为:

if ((*(sit = alreadyCounted.find(str1)).compare(str1) != 0) // WRONG: don't do that!
应该是

if (alreadyCounted.find(str1) != alreadyCounted.end())
…另一个字符串也是如此。不过,我个人会使用另一种技术:当
insert()
插入
std::set
时,您会返回一对迭代器和一个指示器,指示是否插入了对象。后者与当前集的大小一起给出下一个值,例如:

bool result = alreadyCounted.insert(str1).second;
strNum1 = result? alreadyCounted.size() - 1: si->getNum(str1);


总是在尝试读取值后测试输入是否成功,例如,
while(myfile2>>str1>>str2)…
是的,我对它进行了测试,输入成功,我得到了字符串,但无法按升序对它们进行编号。按原样,您的代码将处理最后一行输入两次。在您的情况下,这可能是无害的,但通常不是。我应该如何修复它?对不起,我不太擅长io。我在第一条评论中已经提到过:
w(myfile2>>str1>>str2){…}
。有趣的是,您在读取第一个文件时使用了正确的方法。请始终在尝试读取值后测试输入是否成功,例如,
while(myfile2>>str1>>str2)…
是的,我对它进行了测试,输入成功,我得到了字符串,但无法按升序对它们进行编号。按原样,您的代码将处理最后一行输入两次。在您的情况下,这可能是无害的,但通常不是。我应该如何修复它?对不起,我不太擅长io。我在第一条评论中已经提到过:
while(myfile2>>str1>>str2){…}
。有趣的是,您在读取第一个文件时使用了正确的方法。谢谢,我将尝试修复它。很抱歉,我一直试图理解“std::pairs结果应该是bool,因为这就是
alreadyCounted.insert(str1)的内容.second
将返回?@LachlanEaston:是的,我会更正。不知怎的,我开始认为可以从这个集合中获得计数,但无论如何它不能。@Napalidon:set.find(x)的定义
是将迭代器返回到
set
匹配
x
的元素,或者,如果没有这样的元素,则返回
set.end()
。它没有什么隐藏的地方:如果你有一个包含
n
元素的范围,那么有
n+1
有意义的位置可以讨论:指向每个
n
元素和末尾。
set.end()
但是,它不指向元素,即它不能被取消引用。谢谢,我会尝试修复它。很抱歉,我一直在试图理解“std::pairs”的结果应该是bool,因为这就是
alreadyCounted.insert(str1)的内容.second
将返回?@LachlanEaston:是的,我会更正。不知怎的,我开始认为可以从这个集合中获得计数,但无论如何它不能。@Napalidon:set.find(x)的定义是将迭代器返回到
set
匹配
x
的元素,或者,如果没有这样的元素,则返回
set.end()
。它没有隐藏的东西:如果你有一个包含
n
元素的范围,那么就有
n+1
有意义的位置可以谈论:指向每个
n
元素并在末尾。