为什么在 std::string.find 中使用指针?

3

最初,我使用string_array.find(item)进行搜索,但是编译器不允许。

然后我搜索了一下是否可以使用指针string_array->find(item)来解决问题,但是没有解释。

这是我的代码:

#include<iostream>
#include<string>
using namespace std;
string name [100];
int Jan[100]={0}, Feb[100]={0}, Mar[100]={0}, Apr[100]={0}, May[100] = 0, Jun[100]={0},Jul[100]={0}, Aug[100]={0},Sep[100]={0},Oct[100]={0},Nov[100]={0},Dec[100]={0};
int earning [100];
int main () {
    ifstream load;
    load.open("record.txt");
    if(load.fail()){
        cout << "error in loading data" << endl;
        exit(1);
    } 
    else {
int i = 0;
    string NAME;
    int EARNING;
    int MONTH;
    int dump1;
    char dump2;
    while ( load.eof() != 1 ) {
        int n = 0;
        load >> NAME >> EARNING >> dump1 >> dump2 >> MONTH >> dump2 >> dump1 ;
        n = name->find(NAME);
        if ( n < 0 ) {
            n = i ;
        } 
        else {
    i = i - 1 ;
        }
        name[n] = NAME;
        if ( MONTH == 1) { Jan[n] += EARNING ;}
        if ( MONTH == 2) { Feb[n] += EARNING ;}
        if ( MONTH == 3) { Mar[n] += EARNING ;}
        if ( MONTH == 5) { Apr[n] += EARNING ;}
        if ( MONTH == 5) { May[n] += EARNING ;}
        if ( MONTH == 6) { Jun[n] += EARNING ;}
        if ( MONTH == 7) { Jul[n] += EARNING ;}
        if ( MONTH == 8) { Aug[n] += EARNING ;}
        if ( MONTH == 9) { Sep[n] += EARNING ;}
        if ( MONTH == 10) { Oct[n] += EARNING ;}
        if ( MONTH == 11) { Nov[n] += EARNING ;}
        if ( MONTH == 12) { Dec[n] += EARNING ;}
        i++; 
        }
    }
}

实际上不需要深入查看代码......只需从ifstream读取文件......有一个名为name [100]的数组......使用cin >>输入NAME,然后使用;;find在name [100]中搜索NAME是否存在。 - kit why
2
“但编译器说不行”可能是我听过的有关编译器错误的最好的事情了。我的意思是,编译器正在变得更加自我意识,所以它看到了代码并不想修复它,所以只能说不行。运行 gcc main.c,输出 GCC 4.8.1: No - Cole Tobin
你的while循环不会按照你想要的方式工作。load.eof()只有在你尝试读取并且读取失败因为到达了文件结尾之后才会返回true。你的循环条件应该是读取是否成功(例如 while(load >> whatever) {...})。此外,给变量全大写的名称是不好的风格(那是宏的命名方式),而且两个变量的名称除了大小写不同以外完全相同是非常糟糕的风格。 - sepp2k
当我使用while( load>> wtever ){ ....}时,函数名->find(NAME)不再像以前那样起作用了....所以,我有两个问题.....(1)如果像上面那样使用它(忽略eof的失败),为什么它能够正常工作?..........(2)当我改成while ( load >> wtever){..........}时,为什么它能够正常工作??????? - kit why
3个回答

5

name 是一个包含 100 个字符串的数组。如果你像现在这样仅使用数组名,它会衰变成指向其第一个元素的指针。你的代码:

n = name->find(NAME);

等价于:

n = (&name[0])->find(NAME);

因此你可以看到,该值是一个指针,并且需要使用 -> 运算符进行操作,而不是使用 .。如果有帮助的话,a->b 等同于 (*a).b
我认为你的代码有问题;你确定这就是你想要它工作的方式吗?

是这样的,我们调用一个数组并使用&使其按引用传递以进行修改............ *表示指针,指针的地址在哪里?顺便说一下,谢谢评论。 - kit why

5
这行文字的含义是:
n = name->find(NAME);

这里使用std::find方法在一个std::string上,而不是在整个数组上。它查找的是数组的第一个元素,而不是整个数组本身。此外,这行代码与以下代码没有任何区别:

n = (*name).find(NAME);

所以,您的代码正在搜索 NAME 是否出现在字符串数组的第一个元素中。如果要搜索整个数组,建议使用 std::vector。它提供了标准的迭代器方法:
#include <vector>

std::vector<std::string> name(100);
// ...
it = find(name.begin(), name.end(), NAME);
// std::find return an iterator
if (it == name.end())
    // NOT FOUND
else
    // FOUND

一个小细节:普通数组也可以与std::find一起使用。因此,向量“提供”迭代器方法(暗示数组不提供)并不是真实的情况。 - BartoszKP

1
它可以编译只是巧合 - 它只是在数组的第一个字符串上调用查找函数。我想你想在数组中查找字符串,所以应该使用类似 std::find 的东西。
string *begin = name;
string *end = begin + 100;

if (end == std::find(begin, end, NAME))
{
  // not found
}

但是最好切换到std::vector<std::string>


那么您的意思是将name[100]更改为调用第一个字符串并执行类似于链接列表的指针吗?感谢您的评论......我只是编码的初学者,对于提出这样一个愚蠢的问题感到抱歉...... - kit why
在C++中,表的名称也是指向其第一个元素的指针。因此,没有任何更改,您只是意外地使用了语言的这个特性来访问第一个元素。 - BartoszKP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接