C ++:文件I / O在文件中查找名称

时间:2013-12-08 08:45:28

标签: c++

我有这个函数用于在csv类型的txt文件中查找名称。

void LookupName( string tname ){ //Checks for name in records.txt and enters it if it does not exist
//Pointers
string * names; //Pointer to dynamically created array of names

//Variables
short numLines = 0; //Stores the number of lines in the file
string throwaway = " "; //String used to throw away unwanted content from file
bool found = false; //Used to track if a name is found int he file

//objects
ifstream file ("records.txt"); //Open the file


if (file.is_open()) {

    //Count the number of lines
    numLines = count(istreambuf_iterator<char>(file), istreambuf_iterator<char>(), '\n'); 

    //Reset cursor position
    file.close();
    file.open("records.txt");

    //Create arrays
    names = new string[numLines]; 

    //Loop through the file and fill arrays
    for ( short i; i < numLines; i++ ) {
        getline (file, names[i], ','); //Fill name
        getline (file, throwaway ); //Throw the rest of the line away
    }

    //Loop through names to find the name that was entered
    for ( short i; i < numLines; i++ ) {
        if (names[i] == tname) { // if the name is found
            found = true; //return true
        }
    }

    if ( found == false ) { //if the name is not found
        //This works
        file.close();
        ofstream ofile("records.txt", ios::app);
        ofile << tname << ",0,0\n"; //Add it to the file with 0 wins and losses
        ofile.close();
    }

    //Cleanup
    file.close();
    delete [] names;

} 
}

由于某种原因显然超出了我的调试能力,这不起作用;但是,当我删除第二个for循环并将其与第一个for循环组合时,它确实有效。 (这就是我完全打算离开它的原因,因为它不需要被分成3个循环,但我想知道为什么我自己的教育):

工作:

void LookupName( string tname ){ //Checks for name in records.txt and enters it if it does not exist
//Pointers
string * names; //Pointer to dynamically created array of names

//Variables
short numLines = 0; //Stores the number of lines in the file
string throwaway = " "; //String used to throw away unwanted content from file
bool found = false; //Used to track if a name is found int he file

//objects
fstream file ("records.txt"); //Open the file


if (file.is_open()) {

    //Count the number of lines
    numLines = count(istreambuf_iterator<char>(file), istreambuf_iterator<char>(), '\n'); 

    //Reset cursor position
    file.close();
    file.open("records.txt", fstream::in | fstream::out | fstream::app );

    //Create arrays
    names = new string[numLines]; 

    //Loop through the file and fill arrays
    for ( short i; i < numLines; i++ ) {
        getline (file, names[i], ','); //Fill name
        getline (file, throwaway ); //Throw the rest of the line away

        if (names[i] == tname) { // if the name is found
            found = true; //return true
        }

    }

    if ( found == false ) { //if the name is not found
        //This works
        file << tname << ",0,0\n"; //Add it to the file with 0 wins and losses
    }

    //Cleanup
    file.close();
    delete [] names;

} 
}

任何人都在关注为什么会发生这种情况?

编辑:另外,既然我在问问题(我真的没有尝试过),有没有办法将光标移回文件的顶部而不打开和关闭它?

编辑2:有没有办法告诉程序忽略csv类型行的其余部分,我onyl想要这个特定函数的第一个项目,我觉得使用一次性字符串可能不是最佳方式

edit3:更新为使用fstream而不是1 if和1。

1 个答案:

答案 0 :(得分:1)

有几点要注意代码,希望这可以帮助您使代码更易于管理(和可调试)。但首先,回答您的一个问题 - 是的,您可以使用seekg在文件中设置当前位置。

  1. 更好地使用std::vector - 您不需要两次读取文件并避免自己管理内存,这非常容易出错。
  2. 如果您只需要检查名称是否存在,为什么要将整个列表读入内存?只需在每次迭代时将其读入THE SAME字符串,然后进行比较和分解/继续。
  3. 请记住getline从行的开头读取所有内容,包括空格。这可能是您的程序无效的原因。
  4. [style] void LookupName函数?该函数被称为lookup,但如果找到它查找的内容实际上什么都不做。我建议AddName
  5. 错误处理怎么样?当你无法打开“一切都好”的信号时,你什么都不做。返回错误状态或抛出异常
  6. 重新调试尝试在每次迭代中打印两个字符串,用引号括起来,这样就可以看到白色空格,例如cout << '"' << name << '"';。很有可能你马上就能看到问题。
  7. HTH,享受