尝试从文本文件中打印名字,但同时获取名字和中间名 [重复]

Posted

技术标签:

【中文标题】尝试从文本文件中打印名字,但同时获取名字和中间名 [重复]【英文标题】:Trying to print first name from a text file, but getting both first and middle name [duplicate] 【发布时间】:2019-11-22 00:18:54 【问题描述】:

我正在尝试从格式如下的文本文件中打印名字、中间名和姓氏:

Doe, John Bob
Young, Tim Joe
Washington, George Peter

这是预期的输出:

First name: John
Middle name: Bob
Last name: Doe

First name: Tim
Middle name: Joe
Last name: Young

First name: George
Middle name: Peter
Last name: Washington

我能够正确获取中间名和姓氏,但是当我尝试获取名字时,它显示它是名字和中间名。代码如下:

#include <iostream>
#include <fstream>

using namespace std;

int main()

    //Variable for the text file
    ifstream infile;

    //Opens the text file
    infile.open("data.txt");

    //Variables for the names
    string name;
    string lastName;
    string firstName;
    string middleName;

    //Loops through all the names
    while(getline(infile, name))
    
        //Looks for a comma and space in each name
        int comma = name.find(',');
        int space = name.find(' ', comma+2);

        //Splits the name into first, last, and middle names
        lastName = name.substr(0, comma);
        firstName = name.substr(comma+2, space);
        middleName = name.substr(space+1, 100);

        //Prints the names
        cout << "First name: " << firstName << endl;
        cout << "Middle name: " << middleName << endl;
        cout << "Last name: " << lastName << endl;
        cout << endl;
    
    //closes the text file
    infile.close();

    return 0;
//end main

这是我得到的输出:

First name: John Bob
Middle name: Bob
Last name: Doe

First name: Tim Joe
Middle name: Joe
Last name: Young

First name: George Peter
Middle name: Peter
Last name: Washington

【问题讨论】:

您是否尝试过使用调试器逐行单步执行代码,同时在每个执行步骤检查每个变量的值? 可能重复:How to use string.substr() function? 函数substr()的第二个参数是新字符串中应该包含的字符数。你放入长度的值是从std::string::find()返回的,这个函数返回的值是字符串中的位置(不是从搜索开始的长度)。 【参考方案1】:

您在滥用substr() 方法,来自reference

子字符串是从字符位置 pos 开始并跨越 len 个字符(或直到字符串末尾,以先到者为准)的对象部分。

第二个参数是子字符串的长度。如果你使用

first = name.substr(comma+2, space-comma-2)

你应该得到你预期的行为。

【讨论】:

【参考方案2】:

更简单的选择:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

// is evil. Avoid.
//using namespace std;

int main()

    std::ifstream infile("data.txt"); // open file

    std::string line;
    while(std::getline(infile, line)) // get a line
    
        std::istringstream stream(line); // make an input stream out of the line

        std::string lastName;
        std::string firstName;
        std::string middleName;
        if (getline(stream, lastName, ',') // read up to the comma and discard the comma 
                && stream >> firstName // read up to the next space 
                          >> middleName) // read up to next space, but end of line comes first
        
            std::cout << "First name: " << firstName << '\n'   // endl very expensive
                      << "Middle name: " << middleName << '\n' // save endl for when 
                      << "Last name: " << lastName << '\n'     // you really need it
                      << std::endl; //probably don't even need it here.
        
    
// file closes automatically

Documentation for std::istringstream

补充阅读:Why is "using namespace std;" considered bad practice?和C++: "std::endl" vs "\n"

请注意,这不能处理像 John Jacob Jingleheimer Schmidt 这样的名字,但可以很容易地修改为这样做。

【讨论】:

以上是关于尝试从文本文件中打印名字,但同时获取名字和中间名 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在用户输入中识别名称(从文本文件中识别,然后打印名称)

规范的文件名字分主文件名和扩展名,中间用“.”分割,通常情况下,名字两部分的含义是啥

Windows上获取当前文件夹中某个后缀名的所有文件的名字

反射以及内置方法

java 从txt文本中随机获取名字

bartender能不能从Excel中导入名字(换名字),批打印 btw标签?